I'm currently busy working on an IP ban tool for the early versions of Call of Duty 1. (Apparently such a feature wasn't implemented in these versions).
I've finished a single threaded application but it won't perform well enough for multiple servers, which is why I am trying to implement threading.
Right now, each server has its own thread. I have a Networking class, which has a method; "GetStatus" -- this method is synchronized. This method uses a DatagramSocket to communicate with the server. Since this method is static and synchronized, I shouldn't get in trouble and receive a whole bunch of "Address already in use" exceptions.
However, I have a second method named "SendMessage". This method is supposed to send a message to the server. How can I make sure "SendMessage" cannot be invoked when there's already a thread running in "GetStatus", and the other way around? If I make both synchronized, I will still get in trouble if Thread A is opening a socket on Port 99999 and invoking "SendMessage" while Thread B is opening a socket on the same port and invoking "GetStatus"? (Game servers are usually hosted on the same ports)
I guess what I am really after is a way to make an entire class synchronized, so that only one method can be invoked and run at a time by a single thread.
Hope that what I am trying to accomplish/avoid is made clear in this text.
Any help is greatly appreciated.
Right now, each server has its own thread.
Why do you need two servers in the same application?!? If you break both of the servers out into separate application, then you're still going to have the same issue if both of them try to use the same port... i.e. you have to dedicate a port for each server. If it's really a problem with the threading, then read below for ideas on how to fix this.
It's not possible for two threads to execute properly synchronized methods of the same class... if you have proper synchronization then there is no way to experience what you're describing. Here is what your class should look like:
class Networking
{
public synchronized Status getStatus() {
Status stat = new Status();
// ...
// Get status logic
// ...
return stat;// return the status
}
public synchronized void sendMessage(Message msg) {
// ...
// Send the message logic
// ...
}
}
So as long as you're invoking those methods on the same Networking instance (i.e. you don't have a separate instance of the Networking class for each thread), then you should not see any issues. Here is what the synchronized keyword does for you:
First, it is not possible for two invocations of synchronized methods on
the same object to interleave. When
one thread is executing a synchronized
method for an object, all other
threads that invoke synchronized
methods for the same object block
(suspend execution) until the first
thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a
happens-before relationship with any
subsequent invocation of a
synchronized method for the same
object. This guarantees that changes
to the state of the object are visible
to all threads. (ref)
If you want to have synchronization of the methods across all of the instances of the Networking class then you need to use synchronization statements:
class Networking
{
private static final Object lock = new Object();
public synchronized Status getStatus() {
synchronized(lock){
Status stat = new Status();
// ...
// Get status logic
// ...
return stat;// return the status
}
}
public synchronized void sendMessage(Message msg) {
synchronized(lock){
// ...
// Send the message logic
// ...
}
}
}
will [ I ] still get in trouble if Thread A
is opening a socket on Port 99999 and
invoking "SendMessage" while Thread B
is opening a socket on the same port
and invoking "GetStatus"?
There are two separate issues here. ( beyond the fact that 99999 is not a valid port # )
UDP by it's nature is meant for multiplexed one to many style communications. You can open a single socket and use that single socket to communicate with as many servers as you want. You don't have to worry about synchronization in the sense of one thread sending and another receiving on the same socket or two threads trying to send simultaneously because the read and write operations to the socket are atomic from the applications point of view. When you send on a UDP socket you are invoking a system call which copies N bytes of data from the application's memory space into a buffer in the OS kernel's memory space, and the kernel assembles that data into a UDP packet which is put on a queue for sending - all in a manner which looks atomic to the application. The same occurs when reading from a UDP socket except in reverse; distinct packets exist in a receive buffer in the kernel and when your application reads the socket the data in those packets is atomically copied from the kernel buffer into your application's buffer, one packet per read operation.
The second issue is managing incoming and outgoing data to specific servers. It sounds like you want to have one thread per server which maintains state / status regarding that server. When sending, you don't have to worry about synchronization at all. All the threads can send from the same socket and synchronization is effectively handled by the OS kernel.
However, receiving is a completely different issue. I would recommend having one thread whose only job is to read incoming packets off the socket and de-multiplex them. Each server thread would have a thread safe queue into which the reader thread would copy the incoming packets. Then each server thread doesn't have to worry about anything other than reading packets out of it's own incoming packets queue - it doesn't have to deal with reading from the socket at all.
I think you may be misunderstanding how sockets work and getting client and server ends of sockets confused. If you're sending a message, that usually done from a client socket. These are not bound to a static port number - it's the server socket (the one you call accept() on) that is bound to a specific port.
You can have as many clients as you need (up to some reasonable limit - there is a max of ca. 60,000 client connections) from any one network interface.
For an introduction to client and server-side sockets, see the Sun Lesson: All About Sockets
Related
I have some problems understanding how a socket should be handled. I get that server socket must runs in its own thread, because it must check if there are new connections. Now, i'm not sure if every socket opened by a new connection should runs in a thread.
What i have in mind is checking every x time the socket states. If it has something to be read, then read. If not, check the next socket. I see some examples where this process is done in a thread, but i dont want a socket to do stuff, just want to read if it has some data, and process them.
The answer is no, you don't need to listen in a separate thread. But, just realize that while you are "listening" your entire program will be waiting for that to complete before moving onward.
So unless you are fine with your entire program waiting, I would suggest a separate thread.
You can also have one thread which communicates with all sockets in a round-robin manner. It checks each socket if it has new data, and when it hasn't it checks the next.
Another alternative is to use NIO (New Input/Output).
The idea behind NIO is that you have a thread with one Selector which owns multiple Channels (a channel can be a network socket or any other IO interface). You then call selector.select() in a loop. This method blocks until one or more channels have data, and then returns a set of these channels. You can then process the data the channels delivered.
Here is a tutorial.
The problems with round-robin using available() are many.
It assumes that available() actually works, which isn't guaranteed.
It assumes that all clients need the same amount of service.
N-1 clients wait while one client is serviced.
A non-responsive client can block not only your application but all the other clients.
I'm sure there are more.
Don't do this. Use threads or NIO.
I am working on creating a chat client based on UDP. The main structure is that there is a server where clients register and where clients can also request to form a connection with another client that is registered with the server. The clients are structures as follows using pseudo code:
public UDPClient() {
// Create datagram socket
// Execute RECEIVE thread using datagram socket above
// Execute SEND thread using datagram socket above
}
The idea is to have the send and receive executing on separate threads so I don't get blocked I/O on the receive. Both of these threads have loops within their run methods that allow you to continually send and receive messages. The problem I have is this. If a message comes in on the RECEIVE thread that changes how my SEND should be executing, how do I communicate this to the SEND thread? Do I have to shoot a datagram off to myself or can I communicate this in the code somehow?
Assuming boths threads have no reference to each other, create a third singleton class, which both read/send threads (classes) reference, that has a volatile member field to store the state data you want shared and which has synchronized access.
The volatile keyword, combined with synchronized access, guarantees that a change made to the field by one thread will be seen by another thread. Without this, changes may not be visible due to the java memory model specification.
Edited:
Following "separation of concerns" design guideline, it would be better to not have the read/send threads know about each other and to use a third class to orchestrate their activities/behaviour. Add methods to your read/send classes to stop(), start() etc and call these from the other class.
Using a separate class would also allow:
Behaviour control by other means, for example a "stop sending" button on an admin web page
Allowing multiple threads of each type, yet still having proper control through a central point, perhaps using a pool of such threads (without a separate class, you would have a many-to-many nightmare and lots of code that has nothing to do with the job at hand: ie ending and receiving)
Easier testing of your worker classes, because they do less and are more focused
porting/embedding them stand-alone for other uses
your SEND thread should have public (accesible) method (synchronized if possible) that you should be able to access from your RECEIVE thread. You could use this method to create a boolean flag, string message, etc. that you should always read before you .send(yourPacket); from your SEND thread.
Have a member variable in your READ method that your code can read from and change the SEND method based on that variable.
I am currently trying to write a very simple chat application to introduce myself to java socket programming and multithreading. It consists of 2 modules, a psuedo-server and a psuedo-client, however my design has lead me to believe that I'm trying to implement an impossible concept.
The Server
The server waits on localhost port 4000 for a connection, and when it receives one, it starts 2 threads, a listener thread and a speaker thread. The speaker thread constantly waits for user input to the console, and sends it to the client when it receives said input. The listener thread blocks to the ObjectInputStream of the socket for any messages sent by the client, and then prints the message to the console.
The Client
The client connects the user to the server on port 4000, and then starts 2 threads, a listener and s speaker. These threads have the same functionality as the server's threads, but, for obvious reasons, handle input/output in the opposite way.
The First Problem
The problem I am running into is that in order to end the chat, a user must type "Bye". Now, since my threads have been looped to block for input:
while(connected()){
//block for input
//do something with this input
//determine if the connection still exists (was the message "Bye"?)
}
Then it becomes a really interesting scenario when trying to exit the application. If the client types "Bye", then it returns the sending thread and the thread that listened for the "Bye" on the server also returns. This leaves us with the problem that the client-side listener and the server-side speaker do not know that "Bye" has been typed, and thus continue execution.
I resolved this issue by creating a class Synchronizer that holds a boolean variable that both threads access in a synchronized manner:
public class Synchronizer {
boolean chatting;
public Synchronizer(){
chatting = true;
onChatStatusChanged();
}
synchronized void stopChatting(){
chatting = false;
onChatStatusChanged();
}
synchronized boolean chatting(){
return chatting;
}
public void onChatStatusChanged(){
System.out.println("Chat status changed!: " + chatting);
}
}
I then passed the same instance of this class into the thread as it was created. There was still one issue though.
The Second Problem
This is where I deduced that what I am trying to do is impossible using the methods I am currently employing. Given that one user has to type "Bye" to exit the chat, the other 2 threads that aren't being utilized still go on to pass the check for a connection and begin blocking for I/O. While they are blocking, the original 2 threads realize that the connection has been terminated, but even though they change the boolean value, the other 2 threads have already passed the check, and are already blocking for I/O.
This means that even though you will terminate the thread on the next iteration of the loop, you will still be trying to receive input from the other threads that have been properly terminated. This lead me to my final conclusion and question.
My Question
Is it possible to asynchronously receive and send data in the manner which I am trying to do? (2 threads per client/server that both block for I/O) Or must I send a heartbeat every few milliseconds back and forth between the server and client that requests for any new data and use this heartbeat to determine a disconnect?
The problem seems to reside in the fact that my threads are blocking for I/O before they realize that the partner thread has disconnected. This leads to the main issue, how would you then asynchronously stop a thread blocking for I/O?
I feel as though this is something that should be able to be done as the behavior is seen throughout social media.
Any clarification or advice would be greatly appreciated!
I don't know Java, but if it has threads, the ability to invoke functions on threads, and the ability to kill threads, then even if it doesn't have tasks, you can add tasks, which is all you need to start building your own ASync interface.
For that matter, if you can kill threads, then the exiting threads could just kill the other threads.
Also, a "Bye" (or some other code) should be sent in any case where the window is closing and the connection is open - If Java has Events, and the window you're using has a Close event, then that's the place to put it.
Alternately, you could test for a valid/open window, and send the "Bye" if the window is invalid/closed. Think of that like a poor mans' event handler.
Also, make sure you know how to (and have permission to) manually add exceptions to your networks' firewall(s).
Also, always test it over a live network. Just because it works in a loopback, doesn't mean it'll work over the network. Although you probably already know that.
Just to clarify for anyone who might stumble upon this post in the future, I ended up solving this problem by tweaking the syntax of my threads a bit. First of all, I had to remove my old threads, and replace them with AsyncSender and AsyncReader, respectively. These threads constantly send and receive regardless of user input. When there is no user input, it simply sends/receives a blank string and only prints it to the console if it is anything but a blank string.
The Workaround
try{
if((obj = in.readObject()) != null){
if(obj instanceof String)
output = (String) obj;
if(output.equalsIgnoreCase("Bye"))
s.stop();
}
}
catch(ClassNotFoundException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
In this iteration of the receiver thread, it does not block for input, but rather tests if the object read was null (no object was in the stream). The same is done in the sender thread.
This successfully bypasses the problem of having to stop a thread that is blocking for I/O.
Note that there are still other ways to work around this issue, such as using the InterruptableChannel.
I am writing a java program that needs to continuously accept serialized objects throughout the run of the application. The objects are sent by a server as requested by the user.
My main application initializes the tcp client (extends thread) in its run method, but I am trying to read objects from the line from a function.
Pseudocode follows:
*tcp client extends thread
*global vars: ip, port, socket, oi stream, oo stream, object reference
*run()
make connection
*getObject()
object reference = (object).readobject()
return object
My main application calls client.getObject() in an update loop. there may or not be an object waiting.
Am I going about this the wrong way?
Are you trying to do "classic" server behavior or non-blocking IO?
If it's the former, I'd recommend a blocking queue on the server to accept incoming requests and a pool of threads to process them. Have the server assign a thread to process the request when it comes in until the thread pool is exhausted; queue up requests until threads are freed up and returned to the pool.
Non-blocking IO is another matter entirely. Look at how Netty and node.js are designed and implemented for that.
I would never have a class extend Thread - it's unlikely that you'll add significant new behavior. Implement Runnable instead and give it to a Thread instance to run.
I would suggest your run() method reads all the objects and adds them to a queue.
getOject() takes the next object from the queue.
You can also have a int queueLength() to check how any are waiting.
I'm developing a simple network client/server. The client has a MainConnection class which maintains the connection to the server and starts worker threads based on information coming in. I want the worker threads to send feedback on their progress to the server via the main connection. I’m not sure if I should have a public static synchronized method in MainConnection for sending data, or pass a Session object to the threads which would contain the Socket and a synchronized method for sending data.
It does not matter which design will you choose. It is really up to you. The only thing you should care about is to avoid 2 threads writing to the same stream concurrently. So, you can create your own layer that is synchoronized and used by several threads. Alternatively you can create synchronized output stream and pass it to all threads. This is probably the best approach: in this case each thread just knows to write stuff to the stream. The only layer that knows that stream is synchronized is a factory that creates it.