Win a copy of Node.js Design Patterns: Design and implement production-grade Node.js applications using proven patterns and techniques this week in the Server-Side JavaScript and NodeJS forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Rob Spoor
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Henry Wong
  • Liutauras Vilda
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Tim Holloway
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Mikalai Zaikin
  • Piet Souris

Why won't my client-server program terminate?

 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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?
 
Saloon Keeper
Posts: 13290
292
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • 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?
 
author
Posts: 23908
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
 
Master Rancher
Posts: 4465
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Master Rancher
Posts: 4465
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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: 13290
292
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Master Rancher
Posts: 4465
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
 
You showed up just in time for the waffles! And this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic