pavlee pavlee - 3 months ago 13
Java Question

Receiving data from multiple sockets at once (Multithreading)

I'm new at network programming and i have been searching for a solution to my problem here but couldn't find one. What I want is to have a server that can receive files from multiple sockets at the same time. When a server accepts new connection socket it wraps that socket with a ClientThread class. Here is the code:

public class Server extends Thread {
private ServerSocket server;
private Vector<ClientThread> clients;

@Override
public void run() {
listen();
}

private void listen() {

new Thread("Listening Thread") {

@Override
public void run() {
while (true) {
try {
Socket socket = server.accept();

ClientThread newClient = new ClientThread(socket);
newClient.start();
clients.addElement(newClient);

} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}.start();
}


ClientThread is a private class inside the Server class. It's always listening for an Object from ObjectInputStream, but also I want to be able to receive one big file after the object. And that is why I think i should use multithreading. Here is the code:

private class ClientThread extends Thread {

public Socket socket;
private boolean loggedIn;
private ObjectInputStream ois;
private BufferedInputStream bis;

public ClientThread(Socket socket) {
this.socket = socket;
loggedIn = true;

InputStream is = socket.getInputStream();
ois = new ObjectInputStream(is);
bis = new BufferedInputStream(is);
}

@Override
public void run() {
receive();
}

private void receive() {

while (loggedIn) {
try {
// this method blocks i guess
Object object = ois.readObject();

// after the object comes the large file
byte[] bytes = new byte[SOME_SIZE];

int bytesRead;
int totalRead = 0;

// reading the large file into memory
while ((bytesRead = bis.read(bytes, totalRead, bytes.length - totalRead)) > -1) {
totalRead += bytesRead;
}

// rest of the code for handling received bytes.......

} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
}

}


I'm not sure if receiving data like this is even possible since all these client sockets are sending data to the same port on this server (i guess?). And if clients are sending data at the same time, Server needs to know which data is for which client. Is this already taken care of, or i need entirely different approach here?

I don't know if this is a stupid question, but like I said I'm just starting learning this stuff. Also i couldn't test my program because i don't even have code for the Client yet. Just want to make sure I don't go wrong at the very start. If this is wrong, feel free to post some ideas. :) Thanks!

Answer

For a start it's not bad :) You can improve later on by using a Selector but that's another topic.

Some clarifications though: the ServerSocket listens on a specific port. When a remote client connects to it, a communication channel (i.e. socket) is created. If another client connects, another socket is created. Both sockets are different channels and won't interfere with each other because they are connected to a different remote IP and port.

It all has to do with how TCP headers are formed: a TCP data packet is sent with its header containing the source and destination port, on top of IP header containing the source and destination IP. Those are used to discriminate between the different sockets.

Comments