4

I'm trying to interconnect two socket clients connected to a single remote server. The case is:

  • Client_1] connect to the server
  • Client_2] connect to the server
  • Server] create a tunnel between Client_1 and Client_2
  • Client_1] write "something"
  • Client_2] (that is waiting for some messages) receive "something" by Client_1

and viceversa.

That's my code:

package jtestsock;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;

/**
 *
 * @author massimodeluisa
*/
public class Server extends Thread{

private List<Socket> clients;
private ServerSocket server;
private int port = 5001;
private BufferedReader input;
private PrintWriter output;

public Server() {
    try {
        server = new ServerSocket(port);
        
    } catch (IOException e) {
        System.out.println("Impossibile istanziare il server: "+e.getMessage());
    }
}

@Override
public void run() {
    System.out.println("Waiting for client message...");

    //
    // The server do a loop here to accept all connection initiated by the
    // client application.
    //
    while (true) {
        try {
            Socket socket = server.accept();
            System.out.println("Connection Received!");
            
            clients.add(socket);
            

            /* read response */
            input = new BufferedReader(
                    new InputStreamReader(
                    socket.getInputStream()));

            output = new PrintWriter(
                    new BufferedWriter(
                    new OutputStreamWriter(
                    socket.getOutputStream())));
            
            if(clients.size()>0){
                Socket first    = new Socket();
                Socket second   = new Socket();
                
                first = clients.get(1);
                second= clients.get(2);     // || second = socket;
                
                // ??? Tunneling input and output between two clients
            }
            
        } catch (IOException e) {
            System.out.println("Client connection error: "+e.getMessage());
        }
    }
}
}

Can anyone help me please? Thanks :)

Update:

I would like to make a Point to Point connection between two clients, passing to my server, like a proxy server...

The server must accept more than two connection, and making two threads on the server for writing and reading that redirect messages from one client to the other, the CPU will be saturated.

(Ps. sorry for my English XD)

Community
  • 1
  • 1
Massimo De Luisa
  • 227
  • 1
  • 3
  • 13
  • What's wrong. Where do you need help? Is there an error or exception coming up? – Loki Aug 16 '13 at 12:50
  • Do you plan on only having 2 clients? Because one thing you can do is when one client sends information to the server you could relay that information to the other client. If you plan on having multiple clients though, I would suggest assigning each client a UID. – Josh M Aug 16 '13 at 12:52
  • `clients.size()>0` should be `>=2` as you would want to have atleast two sockets not just one – boxed__l Aug 16 '13 at 12:56

1 Answers1

4

I would do it this way (simplified version):

class Server extends Thread
    ...
        public void run() {
            while (true) {
                try {
                    Socket s1 = server.accept();
                    Socket s2 = server.accept();
                    new Client(s1, s2).start();  // reads from s1 and redirects to s2
                    new Client(s2, s1).start();  // reads from s2 and redirects to s1
                } catch (IOException e) {
                    System.out.println("Client connection error: " + e.getMessage());
                }
            }
        }

class Client extends Thread {
    Socket s1;
    Socket s2;

    Client(Socket s1, Socket s2) {
        this.s1 = s1;
        this.s2 = s2;
    }

    public void run() {
        try {
            InputStream is = s1.getInputStream(); 
            OutputStream os = s2.getOutputStream();
            for (int i; (i = is.read()) != -1; i++) {
                os.write(i);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } 
    }
}
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • Thanks, but I already tried this method and CPU go at 150% of working only with 8 clients... :( And I need that the server could support more than 20 clients. (Actually my MacBook Pro with 2,66Ghz i7 and 8GB 1067MHz DDR3 is the server, but this application will work on a Dell with a xEon E5-2643) – Massimo De Luisa Aug 16 '13 at 13:31
  • Are you sure that the JVM's CPU usage is constantly 150%? It might be laggy during the initialization, doing classloading, JIT, etc. But < 100 threads for blocking IO should not be a problem for a long run. If you plan to serve, like, thousands of clients you might need to look at nonblocking IO options, like [ServerSocketChannel](http://docs.oracle.com/javase/7/docs/api/java/nio/channels/ServerSocketChannel.html) or [netty](http://netty.io/). [This NIO echo server](http://goo.gl/QEjqRs) or [netty's echo server](http://goo.gl/ICVkIs) can be a good starting point. – lyomi Jul 23 '14 at 03:08