Sign in to follow this  

[java] Threads communication in networking

This topic is 4094 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

i've got questions dealing with threads and networking... i have an application using the tcp/ip protocol. when a client connects to the server, a thread dedicated to this client is created. if a client wants to send data to another client, this client needs to send it first to the server, then the server sends it to the other client. I was wondering how the server could send information to a thread? Can threads communicate each others? Cheers !!

Share this post


Link to post
Share on other sites
The clients and server communicate using InputStream and OutputStream objects (this is even more explicit in synchronous IO with Java, NIO complicates the issue a little bit =). The threads you create are used to poll the aforementioned streams, and pull data in and out of them.

The classes responsible by sending data could hold references to the mentioned streams, but this can be dangerous. Rather, write "Processor" threads to monitor Input and Output streams. Explaining: The thread opened to serve the client's request will be constantly polling a Queue of commands that must be sent to the client. Your server will add new commands to this queue as necessary, and the processor thread will write them as fast as it can. I don't see a reason to make threads know about each other in an application; That's the whole point of writting a server application, anyway: manage the data coming from one client to another :p

Share this post


Link to post
Share on other sites
Not sure I understand completely what you're saying, but I'll try a shot at this;

First of all, even for a reasonably small amount of connected clients, creating a thread for each of them on the server is a Bad Thing (TM), because they take up a shitload of processor usage when there's many of them. So, basically, if you insist on having a thread for each client, what you should do is to use the ThreadPool.QueueUserWorkItem() if you're using C# (remember to include the System.Threading namespace!), or look into IOCP if you're using C++. However, it is definately possible to create a really, really good server without creating a thread for each client. RunUO is a testimony to this end.

Also, to have the server communicating with several clients when each client has a thread dedicated to it, you shouldn't somehow send data directly from one thread to another. That's just silly. Just let each thread expose it's own System.Net.Socket instance, and then keep a list of NetworkThread instances (assuming that's what you call your client thread class) in a static class in your server, which you can then poll for activity in the mainloop of your server. If the buffer of one NetworkThread instance (I'm assuming you're using some kind of buffer to receive data) is full or has data in it, just go through the list of NetworkThread instances, and find the right one based on some type of ID (usually ClientID), and then send the data using it's System.Net.Socket instance.

Share this post


Link to post
Share on other sites
@ AfrOm@n

It's Java, dude. And although I agree that creating one thread per client is bad practice, I bet he's doing a simple game with a small number of players, which wouldn't be an issue. Specially if he's doing the game as a learning project.

@ jolyqr

You seem quite confused. Don't you have a Socket instance representing the client? Using that instance, you retrieve a reference to the socket's OutputStream. Use this reference to send data back to the client. If you want to send objects back to the client, use a ObjectOutputStream ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by Son of Cain
@ AfrOm@n

It's Java, dude. And although I agree that creating one thread per client is bad practice, I bet he's doing a simple game with a small number of players, which wouldn't be an issue. Specially if he's doing the game as a learning project.

@ jolyqr

You seem quite confused. Don't you have a Socket instance representing the client? Using that instance, you retrieve a reference to the socket's OutputStream. Use this reference to send data back to the client. If you want to send objects back to the client, use a ObjectOutputStream ;)



You have understand what I'm doing. I'm programming a small game in Java. I'm quite new in socket programming. So I'm using this game as learning project.

Yes, I'm using sockets for my client and server, but I'm still struggling on the way I could use to send pieces of data to specific clients.

Could you illustrate your explanation with some examples ?

Share this post


Link to post
Share on other sites
Quote:
Original post by jolyqr
Could you illustrate your explanation with some examples ?


Instead of writting code that would implement the solution I proposed, I'm going to post a small server class here to get you started and able to communicate; Once you get clients connecting to it, you will catch by yourself many ways of optimizing the stuff.

So here we go:

import java.io.*;
import java.net.*;
import java.util.*;

public class Server implements Runnable {

private ServerSocket servSocket;
private Map < Integer , Socket > clients;

private static int clientId = 0;
private boolean running = false;

public Server() {
clients = new HashMap < Integer , Socket >();
}

public void startServer() {
running = true;
try {

servSocket.bind(new InetSocketAddress(65000));
Thread t = new Thread(this);
t.start();

} catch (Exception e) {
e.printStackTrace();
}
}

public void stopServer() {
running = false;
}

public void run() {
while ( running ) {
try {

// This call blocks until clients connect
Socket client = servSocket.accept();
clients.put( ++clientId, client );

// Give a chance for other threads to run
Thread.sleep( 100 );

} catch (Exception ex) {
ex.printStackTrace();
}
}

// Close all clients' before leaving
for ( Socket s : clients.values() ) {
try {
s.close();
} catch (Exception e) {
e.printStackTrace();
}
}

// Close the ServerSocket
try {
servSocket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}

public void broadcast(Object command) {
for ( Socket client : clients.values() ) {
try {
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
oos.writeObject(command);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

public void sendCommandTo(Integer id, Object command) {
Socket client = clients.get(id);
try {
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
oos.writeObject(command);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}



I wrote it now, on top of my head and without an IDE to back me up, so don't expect it to work right way... But I guess I got it right :D

Son Of Cain

Share this post


Link to post
Share on other sites

This topic is 4094 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this