[java] Threads communication in networking

Started by
5 comments, last by Son of Cain 17 years, 6 months ago
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 !!
Advertisement
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
a.k.a javabeats at yahoo.ca
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.
_______________________Afr0Games
My main problem is I didn't find the way to send data to a specified client...
@ 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 ;)
a.k.a javabeats at yahoo.ca
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 ?
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
a.k.a javabeats at yahoo.ca

This topic is closed to new replies.

Advertisement