0

I am working with Java sockets. I have a server socket and two client sockets. My problem is, that the first client socket submits its message to my server socket, and the message from the second client socket is not arriving at the server socket. That means, that for the first client socket the while loop is interrupted after a succesful message, and the second client ends in an infinite while loop. If I test each client socket seperately in a test class, each client socket is submitting its message correctly to my server socket. By watching TCPView I noticed, that the client socket does not respond, as long as my port is used.

I read, that the second client socket should still respond its message, even if the port was used. In my case, the second client socket should always respond about a second after the first one. But I can't get them to work one after another.

So, here is my code for the method, which is waiting for client messages:

public void listenToSocket()
{
    serverSocket = null;
    thread = null;
    SocketAddress adress = new InetSocketAddress(CommunicationValues.SOCKET_PORT);
    try {
        serverSocket = new ServerSocket();
        serverSocket.setReuseAddress(true);
        serverSocket.bind(adress);

    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
        System.exit(0);
    }




    while(true){
        try
        {
            Socket clientSocket = serverSocket.accept();
            thread = new SocketMessageThread(clientSocket);
            thread.start();         

        } catch (IOException e) {
            System.out.println("MyServerSocket caught an error: \n" + e.getMessage());
            e.printStackTrace();
        }
    }

}

This method is called in a thread. The structure looks like this:

  • SocketListenerThread calls the method listenToSocket() from class SocketListener
  • listenToSocket() is described above
  • The SocketMessageThread is handling the message output of the client socket in its run()-method.

EDIT Here is the code of my SocketMessageThread:

public class SocketMessageThread extends Thread{

private Socket clientSocket;
private static int nameCounter = 0;


public SocketMessageThread(Socket clientSocket) {
    this.clientSocket = clientSocket;
    this.setDaemon(true);
    this.setName("SocketMessageThread" + (nameCounter++));
}

public void run() {
    try (
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));)
    {
        while (in.ready())
        {
            String inLine = in.readLine();
            CommunicationValues.MESSAGE_MEMORIZER = inLine;
        }
        clientSocket.close();

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

EDIT 2 Both clients only communicate with one particular message. E.g. when a client is started up, it mentioned, that the startup was successful with a single message. There are no repeating messages coming from the client sockets until the server sockets catches them. So if the server socket doesn't catch that one message, it's gone, and it won't be sent again by the client socket.

KJaeg
  • 698
  • 3
  • 7
  • 23
  • Your server code is correct as you are starting a new thread for every new client and sending the socket address for each client. For communicating with each client you need to maintain different input output stream. For eg. if there are two clients :- client A and client B. Then Server will accept the connection request 1st then the thread will handle the further request and the thread will communicate with the client by maintaining a input output stream separately. – Pranav Agrawal May 27 '15 at 08:17
  • I think a socket is a one-to-one synchronous communication channel. If your first client doesn't release the socket, the second one will never be able to connect (the server could also interrupt the communication, closing and reopening the socket in order to listen to other clients). – francesco foresti May 27 '15 at 08:17
  • @francescoforesti Your comment doesn't begin to make sense. Accepted sockets are independent. The first client doesn't have to 'release the socket' for the second client to be able to connect. The listen backlog will take care of that, if nothing else does. There is nothing in the question about the second client being unable to connect. – user207421 May 27 '15 at 09:30
  • There is nothing here that waits for client messages. What does the constructor of `SocketMessageThread` do? If it does any I/O on the socket, it shouldn't, as this will hold up and potentially block the accepting thread. All I/O should be deferred to its `run()` method. You need to post more code. – user207421 May 27 '15 at 09:31
  • @PranavAgrawal didn't I do it, when I am creating a new stream for each thread? Look at my added code, maybe you can give me more detail, now. – KJaeg May 27 '15 at 09:39
  • You can't possibly expect @PranavAgrawal to know what you have or haven't done before you've posted the code concerned. Be reasonable. – user207421 May 27 '15 at 09:42
  • @EJP I added the code of my `SocketMessageThread` – KJaeg May 27 '15 at 09:42
  • @EJP You're right, I assumed the message for the second client wasn't reaching the server because of the server socket 'being busy' with the first client. I didn't knew that the server side ip/port could manage different clients simultaneously. – francesco foresti May 27 '15 at 09:47
  • @francescoforesti Of course it can. This is TCP/IP 101. How do you think TCP servers work anyway? One client at a time? Be reasonable. If you don't know, you should be asking questions, not answering them, or commenting on them. – user207421 May 27 '15 at 09:49
  • @EJP well, I always thought patterns like leader/follower address just that. Aside from this, You're right, I should provide answers only if i'm pretty sure about them, and this is indeed my fault. But mine was a comment, wasn't it? Excuse me if I misinterpreted how comments work on stackoverflow, I will take your advice and behave better in the future. – francesco foresti May 27 '15 at 09:55

1 Answers1

1
while (in.ready())
{
    // ...
}

Classic misuse of ready(). Exchange all this for:

String inLine;
while ((inLine = in.readLine()) != null)
{
    CommunicationValues.MESSAGE_MEMORIZER = inLine;
}

Presumably there is more code that you haven't shown us: otherwise all this will do is memorize the last line sent.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I will try it. That .ready()-method bothered me all the time. But since my coworker wrote the code sample, and told me, that's how his client socket worked, I never changed it. – KJaeg May 27 '15 at 09:46
  • I tried it, but it didn't work. Changing your code the way it is results in a NullPointerException. Putting the `MESSAGE_MEMORIZER` into an if with catched Null-values, results in an infinite while-loop. Both happens while waiting for the first client socket. Maybe I should mention, that each client is writing a message on the outstream only once (when it notifies, that the startup of the programm was successful). Using `in.ready()` is working for the first client instead. Btw: Thanks for sharing your ideas with me. – KJaeg May 27 '15 at 10:01
  • No `NullPointerException` is possible if you copied the code above, unless the input stream is null. If there's only one line to read, change `while` to `if`. – user207421 May 27 '15 at 10:13
  • Hehe, funny. I copied your code, but I forgot to remove an additional `inLine = in.readLine()` inside of the if-clause, above the assignment of the `MESSAGE_MEMORIZER`. Since I removed that line, the code runs fine with the `while`, thank you very much for your help! – KJaeg May 27 '15 at 10:44