Continuous running java socket server thread exit on second run - java

I have a java socket client application that send data through TCP over Socket. The data it send is byte array and can send inconsistent data within inconsistent time interval. Although data send at a particular time will be complete in itself and will not have any marker for end of message. Code for client cannot be modified. I had to create a running thread for server so that it will read data whenever it is available on socket.Server application work as - Another class create server socket and start thread for incoming message. Incoming message thread read for message on socket passed while initializing the thread.
The code has following issues.1) It reads only the first data sent from client and thread exits on attempting to read second run2) Cannot use thread to wait for some time period as data can be sent from client in any time interval3) Cannot try opening and closing socket as another thread on server application will send data to client at any time interval.4) Do not want code that will block execution of complete application as another thread of this application will be sending data to client through same socket.
Please help and let me know for any further information. Code as below :
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
public class IncomingMsg extends Thread {
InputStream in =null;
private Socket clientSocket =null;
public IncomingMsg(Socket clientSoc){
this.start();
clientSocket = clientSoc;
}
public void run(){
try {
in = clientSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
byte[] data = new byte[100];
int count = in.read(data); //this is where thread exits on second run as new message may not have been received by the time execution reaches this point.
String message = "";
if(count>0)
{
for(int num=0;num<count;num++)
{message = message + " "+ data[num];}
System.out.println("Received Message from IP:"+clientSocket.getInetAddress()+" Message Byte:" +message);
}
data=null;
} catch (Exception e) {
logger.error(this.getClass().getName()+ ": Exception in receiving message "+ e);
}}} }

There was no issue with the given code. Problem was client application changes local port if it does not receive any message. Since server application is not sending any message, local port of client increment and thus server cannot read data on the second run. Will update answer more if any further clue is received.

Related

How to close TCP connection from server in Java

Here is use case I need to implement in Java:
Server is listening for push messages from some clients
If client has some data to push into server, it opens TCP connection and sends all messages
When client sends last message (special message saying that this is the last one) server should close connection by starting TCP closing handshake
I have problem with last step because I don't know how to close connection from server site. My current code is bellow. How to initiate connection closing TCP handshake form server site? Thank you for any help.
public class Server{
public static void main(String[] args) throws Exception {
while (true) {
int port = AppConfig.getInstance().getPort();
try (ServerSocket socket = new ServerSocket(port)) {
Socket server = socket.accept();
InetAddress ipAddress = server.getInetAddress();
MessageHandler handler = new MessageHandler(ipAddress);
InputStream in = server.getInputStream();
// reads all bytes from input stream and process them by given handler
processStream(in, handler);
in.close();
server.close();
} catch (Exception e) {
LoggingUtils.logException(e);
}
}
}
private static void processStream(InputStream in, MessageHandler handler) throws Exception {
// implementation is omitted
}
}
You've done it. in.close() closes the input stream, the socket output stream, and the socket.
What you should really close is whatever output stream was attached to the socket, to ensure it gets flushed, and you should probably do that in the processStream() method, with a saver server .close() in a finally block in the calling method.
NB Your socket names are really the wrong way round. It is customary to use ServerSocket serverSocket, and Socket socket = serverSocket.accept().
I may be not totally sure about this one, but I would believe that socket.close() will send all the commands (FIN/FIN-ACK)

Java Sockets: One Server and Multiple Clients

So I created a basic client-server program in java. It starts out like this:
Client connects to Server
Server asks for Client's name
Client responds with name
Server greets Client
After this, Client speaks and the Server repeats the words back
I got this to work without too much trouble using this tutorial. The problem comes whenever I try to introduce multiple clients. I thought that it would work because I'm using multiple threads, however, the second clients just hangs until the first client quits and then it starts it work (the server does accept input from the second client, but it doesn't respond with anything until the first client quits).
Here is the code I'm using:
import java.net.*;
import java.io.*;
public class Server extends Thread {
private ServerSocket listener;
public Server(int port) throws IOException {
listener = new ServerSocket(port);
}
public void run() {
while(true) {
try {
Socket server = listener.accept();
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("What is your name?");
DataInputStream in = new DataInputStream(server.getInputStream());
String user_name = in.readUTF();
out.writeUTF("Hello "+user_name);
while(true) {
String client_message = in.readUTF();
out.writeUTF(client_message);
}
}
catch(IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int port = 6006;
try {
Thread t = new Server(port);
t.start();
} catch(IOException e) {
e.printStackTrace();
}
}
}
Can someone explain what I'm doing wrong?
I have looked at the using Runnable instead of Extends Thread, but I ran into even more problems there, so I want to try and work with this first.
Incoming connections are only handled by the line listener.accept();. But after you got a client connected, you're stuck in the while loop. You need to create a new Thread (or Runnable executed on an ExecutorService if you expect high load), and start it, then immediately accept the next connection.
In a nutshell, this is what is going wrong.
You are using exactly ONE thread as the server.
Blocking this thread when you call listener.accept()
This is what you need to do:
Create two classes
1: Server - Similar to what you have now, but instead of doing the actual work of acting as an echo server, it just spawns a new Thread which starts listening on a NEW PORT (which you can select randomly), and sends the client the address for this new port. The client will then get the new port number and would try to connect to the server on the new port.
2: The Echo thread - This starts a new listener on the port passed, and does the job of echoing to whoever is listening.
OR:
You start a UDP server rather than a TCP server, and all this will not matter then, but that is out of the purview of this specific question.

Socket does not receive messages

I have written a simple client and simple udp server that needs to read string messages from particular port. here is the UDP-socket:
public class UDPServer {
// boolean variable defines if the infinite loop
// in startServer() runs or not
private boolean isSwitched = false;
private DatagramSocket socket = null;
public UDPServer(int port) throws SocketException {
socket = new DatagramSocket(port);
Logger.getLogger(Main.class.getName()).log(Level.INFO, "Server started! Bound to port: " + port);
}
//this method start the server and switches on the infinite loop to
// listen to the incoming UDP-packets
public void startServer() throws IOException {
this.isSwitched = true;
Logger.getLogger(Main.class.getName()).log(Level.INFO, "Server starts listening!");
while (isSwitched) {
byte[] size = new byte[30];
DatagramPacket dp = new DatagramPacket(size, size.length);
try {
System.out.println("Debug: receive loop started!");
socket.receive(dp);
System.out.println("Debug: Packet received after socket.receive!");
Thread requestDispatch = new Thread(new Request(dp.getData()));
requestDispatch.start();
} catch (SocketException ex) {
Logger.getLogger(Main.class.getName()).log(Level.INFO, "Stops listening on specified port!");
}
}
}
// this method stops the server from running
public void stopServer() {
this.isSwitched = false;
socket.close();
Logger.getLogger(Main.class.getName()).log(Level.INFO, "Server is shut down after last threads complete!");
}
}
I deploy it on the remote server and switch on the program. The server prints out that it started listening so it reaches the socket.receive() stage. Then I send a UDP-message from a remote client. But nothing happens. The udp-server does not move any further - it justs holds and seems to receive no messages.
I tried to debug the ports with the tcpdump and it shows that messages come to the required port. but java program does not seem to receive them.
When I issue this command on the remote server:
tcpdump udp port 50000
and send a few packets thats what it writes:
12:53:40.823418 IP x.mobile.metro.com.42292 > y.mobile.metro.com.50000: UDP, length 28
12:53:43.362515 IP x.mobile.metro.com.48162 > y.mobile.metro.com.50000: UDP, length 28
I tested your server code locally with netcat and it works just fine, so the problem has to be somewhere else. Are you sure you're actually sending UDP packets? Did you run tcpdump on the remote server? When not, maybe your packets get filtered.
Ok, question resolved. The problem was:
FIREWALL on Red Hat linux, which I successfully switched off for the required port.

Reliable UDP Protocol Implementation in Java - Why does this happen?

I'm currently using a Java implementation of the Reliable UDP protocol, found here. The project has absolutely no tutorials so I have found it really hard to identify problems.
I have set up a client and server. The server runs on localhost:1234 and the client runs on localhost:1235. The server is first established, and loops listening for connections -
try {
ReliableSocket clientSocket = server.socket.accept();
InetSocketAddress clientAddress = (InetSocketAddress) clientSocket.getRemoteSocketAddress();
Logger.getLogger("ServerConnectionListener").info("New Connection from "+
clientAddress.getHostName()+":"+clientAddress.getPort()+" Processing...");
LessurConnectedClient client = new LessurConnectedClient(clientSocket);
ClientCommunicationSocketListener listener = new ClientCommunicationSocketListener(this, client);
clientSocket.addListener(listener);
} catch (Exception e) {
e.printStackTrace();
}
When a connection is established, it creates a listener for events on that socket -
class ClientCommunicationSocketListener implements ReliableSocketListener {
ServerConnectionListener connectionListener;
LessurConnectedClient client;
public ClientCommunicationSocketListener(ServerConnectionListener connectionListener, LessurConnectedClient client){
this.connectionListener = connectionListener;
this.client = client;
}
#Override
public void packetReceivedInOrder() {
connectionListener.server.handlePacket(client);
}
#Override
public void packetReceivedOutOfOrder() {
connectionListener.server.handlePacket(client);
}
}
When a packet is received, it passes it to server.handlePacket, which performs a debug routine of printing "Packet Received!".
My client connects to the server as so -
LessurClient client = new LessurClient();
InetSocketAddress a = (InetSocketAddress) server.getSocket().getLocalSocketAddress();
Logger.getLogger("client-connector").info("Trying to connect to server "+
a.getAddress().toString()+":"+
a.getPort());
client.connect(a.getAddress(), a.getPort());
// LessurClient.connect
public void connect(InetAddress address, int port){
try {
socket = new ReliableSocket(address, port, InetAddress.getLocalHost(), 1235);
isConnected = true;
Logger.getLogger("LessurClient").info("Connected to server "+address.getHostAddress()+":"+port);
} catch (IOException e) {
e.printStackTrace();
}
}
I have linked my code so when I press the key 'Z', it will send a packet to the server as so -
public void sendPacket(GamePacket packet){
if(!isConnected){
Logger.getLogger("LessurClient").severe("Can't send packet. Client is not connected to any server.");
return;
}
try {
OutputStream o = socket.getOutputStream();
o.write(packet.getData());
o.flush();
Logger.getLogger("LessurClient").info("Sending Packet with data \""+packet.getData()+"\" to server "+socket.getInetAddress().toString()+":"+socket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
My problem is, after sending 32 packets, the server no longer receives packets, and after sending 64 packets, it crashes. I have investigated into the code, and it appears that its something associated with packets not being removed from the receive queue, as when I changed the _recvQueueSize variable in ReliableSocket.java:1815 from 32 to 40, I could now send 40 packets without something going wrong.
Could someone help me identify this issue? I've been looking at the code all day.
I managed to fix the problem.
You see, since this is an implementation of RUDP, it extends most of the Socket classes. Specifically, ReliableSocket.getInputStream(), was custom coded to a managed input stream. My problem was, I was receiving the packets, but not reading from the buffer.
When you receive a packet you're supposed to read from the buffer, otherwise the packet will not be dropped from the queue.
So all I had to do, was everytime I received a packet, read the size of the packet, and continue.

How to facilitate communication between the server thread and the multiple client threads in Java

I'm trying to create a client server game using java sockets. I have a thread server which controls the logic of the game. I also have client threads that communicate with the server. I use multiple client handler threads to facilitate server-to-client communication. I use multiple threads to communicate with other client threads using sockets.
Now, I have a problem on how to facilitate communication between the server thread and the multiple client threads. For example, should the server select the next player to play, how should it signal the client handler thread, and in turn communicate with the client thread through sockets?
I have done this before in the following way. I have a Server socket
public Server(int port, int numPlayers) {
game = new PRGameController(numPlayers);
try {
MessageOutput.info("Opening port on " + port);
ServerSocket clientConnectorSocket = new ServerSocket(port);
MessageOutput.info("Listening for connections");
while (!game.isFull()) {
// block until we get a connection from a client
final Socket client = clientConnectorSocket.accept();
MessageOutput.info("Client connected from " + client.getInetAddress());
Runnable runnable = new Runnable() {
public synchronized void run() {
PRGamePlayer player = new PRGamePlayer(client, game);
}
};
new Thread(runnable).start();
}
} catch (IOException io) {
MessageOutput.error("Server Connection Manager Failed...Shutting Down...", io);
// if the connection manager fails we want to closedown the server
System.exit(0);
}
}
Then on the client side, I have something like this..
public void connect(String ip) {
try {
comms = new Socket(ip, 12345);
comms.setTcpNoDelay(true);
// get the streams from the socket and wrap them round a ZIP Stream
// then wrap them around a reader and writer, as we are writing strings
this.input = new CompressedInputStream(comms.getInputStream());
this.output = new CompressedOutputStream(comms.getOutputStream());
this.connected = true;
startServerResponseThread();
} catch (IOException e) {
ui.displayMessage("Unable to connect to server, please check and try again");
this.connected = false;
}
if (connected) {
String name = ui.getUserInput("Please choose a player name");
sendXML(XMLUtil.getXML(new NameSetAction(name, Server.VERSION)));
}
}
/**
* This method sets up the server response thread. The thread, sits patiently
* waiting for input from the server, in a seperate thread, so not to hold
* up any client side activities. When data is recieved from the server
* it is processed, to perform the appropriate action.
*/
public void startServerResponseThread() {
// create the runnable that will be used by the serverListenerThread,
// to listen for requests from the server
Runnable runnable = new Runnable() {
public void run () {
try {
// loop forever, or until the server closes the connection
while (true) {
processRequest(input.readCompressedString());
}
} catch (SocketException sx) {
MessageOutput.error("Socket closed, user has shutdown the connection, or network has failed");
} catch (IOException ex) {
MessageOutput.error(ex.getMessage(), ex);
} catch (Exception ex) {
MessageOutput.error(ex.getMessage(), ex);
} finally {
(PRClone.this).connected = false;
// only shutdown the server if the listener thread has not already been
// destroyed, otherwise the server will have already been shutdown
if (serverListenerThread != null) {
// shutdown the thread and inform the application the communications has closed
MessageOutput.debug("Shutting down server listener Thread");
}
}
}
};
// create the thread
serverListenerThread = new Thread(runnable);
// start the thread
serverListenerThread.start();
}
The client is able to send requests to the server via the outputstream, and read server data from the input stream.
The server can accept requests from the client, and process it in the GameController, and can also send notifications from the server using outputstream, again in the GameController.
EDIT: Also, I should note that all my communication is done via XML, and the controller on the client or the server decodes the XML and performs the relevant request.
Hope this helps. It certainly does the job for me, and allows my multi-player games to work well.
I suspect that your client threads are hanging on a blocking read operation. To "release" these threads and make them send data instead, you'd have to interrupt them through thread.interrupt(). (Which would cause the blocking read to throw an InterruptedException.)
However, I've written a few network games myself, and I would really recommend you to look into the java.nio packages and especially the Selector class. Using this class you could easily make the whole server single-threaded. This would save you a lot of headaches when it comes to synchronizing all those client threads.
I think using an existing communication infrastructure like ActiveMQ would be very useful here to deal with the low-level piping stuff and allow you to tackle the game design issues at a higher conceptual level rather than dealing with the low-level intricacies.
That being said. If I understood you then you have a game-client with mutiple threads, one of which deals with comms to the server. On the server there is a comms thread for each client and the game server logic.
I would only use sockets for remote communication and Queues for communication between the server threads. On the queues send immutable objects (or copies) back and forth so you do not need to synchronize access to the data in the messages. As a base for synchronisation you can block on the Socket or a BlockingQueue, then you do not need to manually synch things, however this requires careful protocol design.

Categories