2

I'm programming a client server app. I'm wondering to end the connection, which side should decide to end it, client or server?

Then if for example the client did it, should the server still keep open or not?

Suppose we have the below codes for each client and server:

           socket = new Socket("127.0.0.1",3000);
........

            socket.close();

or

            serverSocket = new ServerSocket(3000);
            socket = serverSocket.accept();
......

            serverSocket.close();

EDIT: according to the matt's answer, i pot my code here and let see why my code doesnt work:

generally, i have a Jframe program as client which will connect to a server and while its open, i want the connection being alive, since it send info to the server and server should response for the result. but if i dont use closing the socket from server it gives an error and if i use, after once calculation, it closes the connection:

Server

        private static PrintWriter toClient;
        private static BufferedReader fromClient;


  public static void run() throws IOException, SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException, SAXException, XPathExpressionException
        {
  
        
        System.out.println("Server is waiting for connections...");
   
        while(true)
        {
                 openStreams();
                  processClient();
                  closeStreams();
 }
     
    }

OpenStream:

  public static void openStreams() throws IOException, SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException, SAXException, XPathExpressionException
            {
            serverSocket = new ServerSocket(3000);
            socket = serverSocket.accept();
                System.out.println("Connected");

             toClient = new PrintWriter(socket.getOutputStream(),true);
            
            fromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            

            }

Closestearms:

   public static void closeStreams() throws IOException
            {
            fromClient.close();
            toClient.close();
            socket.close();
            serverSocket.close();
                System.out.println("Disconnected");
        }
          

the error i receive if i remove the closestream();

at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359)
    at java.net.ServerSocket.bind(ServerSocket.java:319)
    at java.net.ServerSocket.<init>(ServerSocket.java:185)
    at java.net.ServerSocket.<init>(ServerSocket.java:97)
Community
  • 1
  • 1
lonesome
  • 2,503
  • 6
  • 35
  • 61

3 Answers3

2

Depends on your application's logic. Both are valid, and you must make sure your code is correct in both cases, since if the connection is broken "involuntarily" (like a network drop), it will appear to both sides as if the other side had closed the connection.

So your code must handle both cases gracefully.

Your closing code is suspicious: you're closing the listening socket, which is unusual. You should only close the listening socket when you don't want any more incoming connections (i.e. usually for a server, when you're shutting down the server).
Only close the socket you got from accept to end that "conversation", and don't re-open the server listening socket. (The exception you're getting might be an "Address already in use" in this case. See How to set reuse address option for a datagram socket in java code? for an example of how to avoid that specific problem.)

Community
  • 1
  • 1
Mat
  • 202,337
  • 40
  • 393
  • 406
  • but im confused, because if client end it, then server should do the **socket.close** or not? and vice versa – lonesome Apr 01 '12 at 10:47
  • Once the socket has been closed on one side, the other will get exceptions if it tries to run methods on it that require the connection to be open. It doesn't matter if it is the server or the client; once the connection is open, both are equivalent from the TCP point of view. – Mat Apr 01 '12 at 10:52
  • Re-read my answer: you must handle all cases gracefully. That means handling exceptions if they happen, and closing streams you're not using anymore. (BTW: please report the actual exception, not just stack traces - both are necessary to have a meaningful error message.) – Mat Apr 01 '12 at 11:08
  • The very first line of the stack trace should contain the actual exception; or you're doing something funny to print it. – Mat Apr 01 '12 at 11:10
  • i know where is the exception, but it happens in run time, maybe thats why it doesnt shows the exception – lonesome Apr 01 '12 at 11:14
  • Exceptions _only_ happen at runtime, so your last comment doesn't make much sense to me. I added some notes about something you're not doing correctly in your code. – Mat Apr 01 '12 at 11:15
  • i mean my program runs with no exception, then after some min, when it tries to send info, the exception happens, i dont know i made it clear.because sometimes the program cant even run because of exception hmmm, was it meaningful now? :P – lonesome Apr 01 '12 at 11:20
  • Did you read what I edited in to my answer? The partial exception you're showing matches the "address already in use" symptom I'm describing, and it is happening because you are closing the wrong socket. – Mat Apr 01 '12 at 11:22
  • you didnt get my point, i get that exception if i dont close the socket. i mean if i remove the closestreams(); from server, after once sending info from client to the server, server use it as data needed then when process ends, if no closing socket, then the exception happens, but if i keep the closestreams(); in my server side, it disconnect which i dnt want, cause i want client close the stream. – lonesome Apr 01 '12 at 11:25
  • you didn't read my answer. " and don't re-open the server listening socket. " That is what is causing your problem (well, it sounds like it is, but since you're not printing out or catching the exception correctly, it is hard to be sure.) – Mat Apr 01 '12 at 11:27
  • well, i sent all the IDE shows me as an error...no info about what is the exceptioon :( – lonesome Apr 01 '12 at 11:28
  • 1
    @user1064929: please please please read my answer and my previous comment, and try to implement your code so that you don't close _and_ **don't reopen the server listening socket** (`serverSocket` in your code). That should make the problem go away. – Mat Apr 01 '12 at 11:30
  • i think the key point was here: in **while(true)** that made the socket open again :) and i think problem solved, at least for now :) – lonesome Apr 01 '12 at 11:46
0

Either end may close the connection - neither is "more correct".

However, it is important to clear up one (seeming) misunderstanding in your code: closing the ServerSocket is not closing the socket that represents the connection between the two end points.

The ServerSocket is a listening socket on a port. When a client makes a connection to the ServerSocket on that port, a (normal) Socket is returned by the ServerSocket.accept() method. Communication between your two end points uses the input and output streams associated with this (normal) Socket.

Closing the ServerSocket just stops listening on the well known port and doesn't relate to the established sockets.

Greg Kopff
  • 15,945
  • 12
  • 55
  • 78
0

The socket is present in both the client and server program. Closing any socket will throw exception on the other side.

Harbeer Kadian
  • 364
  • 2
  • 14