• Post Reply Bookmark Topic Watch Topic
  • New Topic

Why won't my client-server program terminate?  RSS feed

 
Jonas Treamsworth
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So my program is supposed to be a simple client-server connection program, with the client sending messages to the server and server sending some to the client. Now this works fine - the message sending is all good, but the program doesn't terminate. My code:

SimpleClient.java


SimpleServer.java:


WritersThread.java:


Output:
SimpleClient:
SimpleServer:

As you can see, the programs don't end (intellij usually shows something along the lines of "Process terminated"). Force-stopping either one of the two gives the following stacktrace in the OTHER file (here I ended SimpleClient, so the stacktrace was in SimpleServer not in SimpleClient):


Line 29 in SimpleServer.java is: . Ending the server instead of the client leads to the same line (the while loop) but in the client instead of the server. So my initial guess was that after termination of one socket (either server or client), the while loop tried to continue access through the BufferedReader, thus causing a SocketException. I guessed that the while loop continued running (even though I sent only 4 strings from either side) because the BufferedReader was reading some sort of "blank line" which wasn't null, thus leading to an infinite while loop (which threw an exception upon closure of the other side). To verify this, I added a System.out.println("a" or "b"). If my theory was correct I'd be seeing endless a's or b's depending on the file. However as you can see the output terminates there - so my theory is probably wrong. Can you help out?
 
Stephan van Hulst
Saloon Keeper
Posts: 7993
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, your loop continues until your reader returns null. The reader will only return null when the socket on the other end has sent a connection termination sequence. You need a way of determining when you want to finish the conversation, and after that call socket.shutdownInput() and socket.shutdownOutput().

Another issue in your application is that you're interacting with the Thread class directly. Don't do this. Use an ExecutorService instead.
 
Jonas Treamsworth
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Well, your loop continues until your reader returns null. The reader will only return null when the socket on the other end has sent a connection termination sequence. You need a way of determining when you want to finish the conversation, and after that call socket.shutdownInput() and socket.shutdownOutput().

Another issue in your application is that you're interacting with the Thread class directly. Don't do this. Use an ExecutorService instead.


But if that is correct, shouldn't a or b be printed constantly?
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jonas Treamsworth wrote:
But if that is correct, shouldn't a or b be printed constantly?


Why should a or b be printed constantly? The threads are blocked waiting for more input -- for input that will never arrive.  And as long as the sockets are open, they will continue to wait for the input.

Henry
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
the program doesn't terminate.

How are the programs supposed to know when to terminate?
You could design a protocol where if the client sends a special message, then the server will respond with a special message and terminate and the client will terminate.
 
Jonas Treamsworth
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Norm Radder wrote:How are the programs supposed to know when to terminate?
You could design a protocol where if the client sends a special message, then the server will respond with a special message and terminate and the client will terminate.

Yeah that's what I plan to do when I make this a proper user input based service. For now, I simply shut input once I finish printing.

Stephan van Hulst wrote:Well, your loop continues until your reader returns null. The reader will only return null when the socket on the other end has sent a connection termination sequence. You need a way of determining when you want to finish the conversation, and after that call socket.shutdownInput() and socket.shutdownOutput().

Another issue in your application is that you're interacting with the Thread class directly. Don't do this. Use an ExecutorService instead.

So I implemented your corrections as such:

SimpleClient.java:

SimpleServer.java:

I've now used ExecutorServices and lamba expressions, as well as sock.shutDownInput() calls.

The result is still the same - output is correct, but program doesn't terminate.
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For now, I simply shut input once I finish printing. 

How does that tell the programs to terminate?
 
Stephan van Hulst
Saloon Keeper
Posts: 7993
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And how do you know you're finished printing?
 
Jonas Treamsworth
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alright; I made further modifications - this time to WritersThread (and removed the shutdown lines from the client and server.), and now it works fine. Code for future viewers (and a small comment at the end):

SimpleClient.java:

SimpleServer.java:

WritersThread.java:


Now the thing is, MOST of the time the output is like this
Output from SimpleClient:

Output from SimpleServer:


Sometimes, however the endstring line appears in the middle of the output; but I understand that I can do pretty much nothing about it, as order of execution for the ExecutorServices isn't in my control. However, it doesn't really matter here anyway; in a real world scenario I wouldn't be printing that string. Thanks to everyone who helped!
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A problem I see:  the test for the end String uses == instead of the equals method.  Always use the equals method to compare the contents of String objects.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!