aspose file tools*
The moose likes Sockets and Internet Protocols and the fly likes How to properly close a socket connection. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Sockets and Internet Protocols
Bookmark "How to properly close a socket connection." Watch "How to properly close a socket connection." New topic
Author

How to properly close a socket connection.

Charles Sexton
Ranch Hand

Joined: Sep 26, 2013
Posts: 193
Is this the proper way to close a connection between client and server?

Joe Harry
Ranch Hand

Joined: Sep 26, 2006
Posts: 9426
    
    2

You should make sure that your socket.close runs whatever happens. One way to do this is to move it to the finally block.


SCJP 1.4, SCWCD 1.4 - Hints for you, Certified Scrum Master
Did a rm -R / to find out that I lost my entire Linux installation!
Charles Sexton
Ranch Hand

Joined: Sep 26, 2013
Posts: 193
Joe Harry wrote:You should make sure that your socket.close runs whatever happens. One way to do this is to move it to the finally block.


So basically I should just call my closeConnection method with a finally block at the end of my code/infinite while loop for server. Thank You for the help
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

Preferably, you should make your class Closeable and then use a try-with-resources in your calling code.

That's no what Joe meant though. Within your closeConnection() method (or close() method, if you're going the Closeable way), you should make sure that each of your close operations gets called regardless of what happens. You need three nested try-finally statements.
You can see this kind of code looks horrible. There might be a little hack that looks much better, but I haven't tested if it works:
Charles Sexton
Ranch Hand

Joined: Sep 26, 2013
Posts: 193
Stephan van Hulst wrote:Preferably, you should make your class Closeable and then use a try-with-resources in your calling code.

That's no what Joe meant though. Within your closeConnection() method (or close() method, if you're going the Closeable way), you should make sure that each of your close operations gets called regardless of what happens. You need three nested try-finally statements.
You can see this kind of code looks horrible. There might be a little hack that looks much better, but I haven't tested if it works:


Thank you Stephen for clearing that up.....
Charles Sexton
Ranch Hand

Joined: Sep 26, 2013
Posts: 193
Stephan van Hulst wrote:Preferably, you should make your class Closeable and then use a try-with-resources in your calling code.

That's no what Joe meant though. Within your closeConnection() method (or close() method, if you're going the Closeable way), you should make sure that each of your close operations gets called regardless of what happens. You need three nested try-finally statements.
You can see this kind of code looks horrible. There might be a little hack that looks much better, but I haven't tested if it works:


How would you say this looks with a quick glimpse? Professional?

Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

A few remarks.

You're writing SERVER_SOCKET and SERVER_PORT with capital letters, but they're not constants. Also, your class name shouldn't have an underscore.

Most of your fields can be final, but they're not.

I don't know why, but using a blocking operation (accept()) in a constructor seems a bit fishy to me. Also, your server can only serve one client at a time, and since you can't control who is going to connect to your server, this may be a problem. I would create handler objects for each incoming connection.

You're catching too many exceptions. What use is it to have a Server_Controller object fully constructed, if it encountered I/O exceptions while setting up? Just propagate the exceptions.

You're using nouns for methods. Use verbs instead: initOutputStream() and initInputStream().

You don't need to put out.flush() in a finally clause. If out.writeUTF(message) fails, then there's nothing to flush.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

I have a small example project to show a generic simple server. It can be imported in Eclipse and opened in NetBeans.


[Download simple-server.zip] Download

Charles Sexton
Ranch Hand

Joined: Sep 26, 2013
Posts: 193
Stephan van Hulst wrote:A few remarks.

You're writing SERVER_SOCKET and SERVER_PORT with capital letters, but they're not constants. Also, your class name shouldn't have an underscore.

Most of your fields can be final, but they're not.

I don't know why, but using a blocking operation (accept()) in a constructor seems a bit fishy to me. Also, your server can only serve one client at a time, and since you can't control who is going to connect to your server, this may be a problem. I would create handler objects for each incoming connection.

You're catching too many exceptions. What use is it to have a Server_Controller object fully constructed, if it encountered I/O exceptions while setting up? Just propagate the exceptions.

You're using nouns for methods. Use verbs instead: initOutputStream() and initInputStream().

You don't need to put out.flush() in a finally clause. If out.writeUTF(message) fails, then there's nothing to flush.


Thank you for your information and your download. I still have a lot more to learn it seems like. I was trying to just setup a professional client/server connection then make it multithreaded. Seems like I need to study a lot more before moving forward. Again I can't say how thankful I am for the download as I will be studying your logic for the next few days.
Charles Sexton
Ranch Hand

Joined: Sep 26, 2013
Posts: 193
Stephan van Hulst wrote:I have a small example project to show a generic simple server. It can be imported in Eclipse and opened in NetBeans.


I was able to understand the code but for one line. This line also has an error when I imported but I don't care about the error just about learning the logic..



Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

Ahh yeah, I'm sorry, I probably should have clarified that it uses lambda's.

The submit method takes either Runnables or Callables. The executor must know what to run/call, after all.

() -> {} is a construct called a lambda. You can consider it like a method, without a name. In the parentheses you put the method parameters, and in the braces you put the method body. So I actually submitted a method to the executor. Here's how you would do the same thing before Java 8:
You can see this is much more verbose. In Java 8, instead of using anonymous instances of an interface (in this case Runnable), you can just use a lambda, as long as the interface you're implementing has exactly one method (in this case run()).
Charles Sexton
Ranch Hand

Joined: Sep 26, 2013
Posts: 193
Stephan van Hulst wrote: I would create handler objects for each incoming connection.


So I do have a question on the code below.



This line of code above will create an instance of the interface hanlderFactory and then create a new handler. The new handler is determined by the factory class in ExampleClientHandler. The factory class returns a new instance of the ExampleClientHandler by then you call the handle method. Does that seem correct? I'm a bit confused on creating an instance of an interface. I apologize for the multiple questions but I am just trying to study to learn as much as I can. One day I will be helping others learn here on java ranch. This is absolutely a great website.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

The above does *not* create an instance of ClientHandlerFactory. The factory is passed in the constructor, and assigned to handlerFactory. Its runtime type is ExampleClientHandler.Factory.

When createHandler(socket) is called, the runtime type of the result is ExampleClientHandler. You then call the handle() method on this handler.

You could also break up the line in two pieces:
Here you can see that while Server doesn't know what specific type of handlers it's working with (you need to assign the result to ClientHandler, you can't assign it to ExampleClientHandler), it doesn't really matter because all it cares about is that you can call the handle() method.

This is called "programming to an interface". Working with one type (ClientHandlerFactory) while the runtime type differs (ExampleClientHandle.Factory) is called polymorphism.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

Maybe I should clarify why I used a factory.

Since you don't want the server to know how to deal with clients (because then you would need to write a complete server for each protocol, now you can just reuse the same class), the server needs access to something that *does* know how to communicate with the client, for instance, a TicTacToeClientHandler, or a HttpClientHandler, or something else still.

You will want to create one handler instance per connection, because the handler might need to keep track of state information (for instance, how far the game of Tic Tac Toe has progressed). So you shouldn't pass the server an instance of a handler, because then the server would only be able to handle one connection at a time. You should pass the server a way to create one handler for each connection: A factory.

Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

For other readers, I'll reproduce the Server code:
Charles Sexton
Ranch Hand

Joined: Sep 26, 2013
Posts: 193
Stephan van Hulst wrote:Maybe I should clarify why I used a factory.

Since you don't want the server to know how to deal with clients (because then you would need to write a complete server for each protocol, now you can just reuse the same class), the server needs access to something that *does* know how to communicate with the client, for instance, a TicTacToeClientHandler, or a HttpClientHandler, or something else still.

You will want to create one handler instance per connection, because the handler might need to keep track of state information (for instance, how far the game of Tic Tac Toe has progressed). So you shouldn't pass the server an instance of a handler, because then the server would only be able to handle one connection at a time. You should pass the server a way to create one handler for each connection: A factory.



Here is a video from where I learned the factory pattern. You example above is clear but for future readers who want more insight. https://www.youtube.com/watch?v=ub0DXaeV6hA&list=PLF206E906175C7E07
Charles Sexton
Ranch Hand

Joined: Sep 26, 2013
Posts: 193
Stephan van Hulst wrote:This is called "programming to an interface". Working with one type (ClientHandlerFactory) while the runtime type differs (ExampleClientHandle.Factory) is called polymorphism.


I think the programming to an interface part had me a little confused. I will do more studying and thank you for the useful code. I will implement a server that uses the factory design pattern without copying your code to learn.

http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface

This really cleared up what you mean by programming to an interface.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: How to properly close a socket connection.