About the Java socket

Source: Internet
Author: User
Tags set socket connection reset

1. Understanding of parameters in the new Socket ()

Server side:

    • Call ServerSocket ServerSocket = new ServerSocket (1287,2), the backend server side opens the specified port 1287, and the PID 5449 is bound.

Client side:

    • Call SOCKET socket = new socket (remoteaddress, 1287), client side will bind the client's PID to a random unused port ;

    • Call SOCKET socket = new socket (remoteaddress, 1287, localaddress, 1288), client side will bind the client's PID to the specified port 1288;

2. Understanding of the Backlog,connectiontimeout,so_timeout parameter 2.1. Testing process and phenomena

Tests have shown that the test program behaves differently on Windows and on Linux.

2.1.1. On Linux platforms (both server and client are on Linux)

Start server in Eclipse and then start the 1th client C1, at which point C1 is connected to the server normally and returns:

The server side also prints out the appropriate information:

Start the 2nd client C2, at which time C2 waits for the server's "HI" response, the server side of the queue number is 1;

Start the 3rd client C3, at which time C3 waits for the server's "HI" response, the server side of the queue number is 2;

Start the 4th client C4, at which time C4 waits for the server's "HI" response, the server side of the queue number is 3;

Start the 5th client C5, at which time C5 waits for the server's "HI" response, the server side of the queue number is 4;

Start the 6th client C6, at which time C6 waits for the server's "HI" response, the server side of the queue number is 5;

After waiting about 100s, C5 and C6 all returned the error message: (client side is not set socket.setsotimeout (5000);)

The C2, C3, and C4 are still in a waiting state with no output:

At this point the server side has a queue number of 3, which is more than the server -side setting (serversocket serversocket = new ServerSocket (1287,2) ), the number of queues is more than 2 1. In fact, after further testing, the server-side setting has a queue number of 1 or 3 o'clock, and the actual number of queues on the server side is 1 more than the set value.

2.1.2. On Windows platforms (both server and client are on Windows)

Start the server in CMD and then start the 1th client C1, at which point C1 normally connects to the server and returns:

The server side also prints out the appropriate information:

Start the 2nd client C2, at which time C2 waits for the server's "HI" response, the server side of the queue number is 1;

Start the 3rd client C3, at which time C3 waits for the server's "HI" response, the server side of the queue number is 2;

Start the 4th client C4, at this time C4 immediately returned the error message: (client side is not set socket.setsotimeout (5000);)

The C2 and C3 are still in a waiting state without any output:

At this point the server side has a queue number of 2, with the server -side settings (serversocket serversocket = new ServerSocket (1287,2) ) has a queue number of 2 equals . In fact, after further testing, the server-side setting has a queue number of 1 or 3 o'clock, and the actual number of queues on the server side is equal to the value set.

2.2. Client connection to server process

(1). Server-side initialization of serversocket and listening ports

ServerSocket serversocket = new ServerSocket (1287,2);

Socket socket = serversocket.accept (); At this point, if there is no client connection, that is, the server side of the waiting queue is empty, then the server side blocking

(2). Client side initializes the socket and connects to the server

Socket socket = new socket ();

Socket.connect (New Inetsocketaddress (Inetaddress.getbyname ("22.11.143.60"), 1287), 1000);

(Socket.setsotimeout (5000);)

(3). The server-side accept () call takes the client out of the waiting queue and returns

Socket socket = serversocket.accept ();

(4). Server side interacts with client side via the returned socket

2.3. Guessing conclusions

According to the above phenomenon guess, the so-called "queuing queue" should be controlled at the TCP layer, specifically:

"Interpreting features in the diagram"

Connection Queue ( Connection queue): All client TCP connection requests, first entering the connection queue, three handshake, three handshake success marks the connection establishment (established), after the connection is established, the client request is removed from the queue and enters the accept queue. Three handshake the process of establishing a connection is generally fast, within 1ms of the LAN.

ConnectionTimeout is the time-out period from entering the connection queue, making three handshakes, and establishing connections to be taken out of the queue, generally this does not time out. ConnectionTimeout can be used on the client through Socket.connect (new Inetsocketaddress (Inetaddress.getbyname ("22.11.143.60"), 1287), to set.

ACCEPT Queue : After the connection is established, the client request is placed in the Accept queue, waiting for the service-side application to call Serversocket.accept () to remove the client request from the Accept queue and interact with it. Of course, if the server application calls socket socket = serversocket.accept (), when the Accpet queue is empty, then the server application is blocked until the accept queue is not empty.

The Max queued backlog for the Accept queue controls how many client requests the queue can hold, and rejects the redundant client service when the number of client requests is greater than the backlog. Server-side applications can set up the backlog by calling ServerSocket ServerSocket = new ServerSocket (1287,2).

In the Accept queue, each client request has a so_timeout parameter that controls the client's timeout during that time-from entering the accept queue to taking it out, the service-side accept () return, the service-side writing the reply data to the socket, The client receives a reply from the server. If the client does not receive a reply from the server within the So_timeout time, the client is.readline the read timed out exception, such as. The client can set so_timeout by callingsocket.setsotimeout.

Port-pid mapping Table : When a client request is taken out of the accept queue, it needs to be handed over to the server application, so it needs to know which server application it should be given, and what its PID is, so it needs a mapping relationship like the port-pid mapping table. When the server-side application (pid=1234) is started, call ServerSocket ServerSocket = new ServerSocket (1287, 2), which means that the service binds 1287 of this port, A record "port:1287, pid=1234" should be added to the port-pid mapping table. This way, when a client request is taken out of the port1287 's accept queue, it is known that it should be given to a server application with a PID of 1234.

"Description C1-c6 Connection Server the process "

On the server side, when application tier application 1 calls ServerSocket ServerSocket = new ServerSocket (1287,2), the TCP layer adds a record "port-pid" to the PORT1,PID1 mapping table to bind And the TCP layer opens up new space for Port1, which stores the port, connection queue, and accept queue, and sets the backlog for the Accpet queue. Then apply 1 to call socket socket = serversocket.accept () to listen to the accept queue.

When C1 calls Socket.connect (new Inetsocketaddress (Inetaddress.getbyname ("22.11.143.60"), 1287), 1000), when the request is initiated, the C1 is routed to the server-side machine, The TCP layer is reached from the physical layer, link layer, and IP layer. After arrival, first enter the connection queue 1, set connectiontimeout, three times handshake, successfully enter the Accept queue, and call Socket.setsotimeout (5000); set so_timeout. Since application 1 is blocking in accept (), C1 is removed from the queued queue, then queries the PORT-PID mapping table, decides PID1, sends C1 to PID1 process application 1, and then applies 1 accpet () to return and generate a socket to interact with C1.

When C2 calls Socket.connect (new Inetsocketaddress (Inetaddress.getbyname ("22.11.143.60"), 1287), 1000); C2 enters the accept queue after three handshakes in the connection queue, and calls Socket.setsotimeout (5000); set so_timeout. Because application 1 does not call accept () at this time, C2 waits in the queued queue. C3, C4, C5, C6 repeat this process. If the number of elements in the queued queue is greater than the maximum number of queued backlog1, then TCP rejects the redundant client service.

"Interpreting Test Phenomena"

Therefore, the following can explain the test phenomenon (PS. The client side is not set in the test Socket.setsotimeout (5000);)

If set backlog1 = 2, then, in the Linux environment C5 and C6 will be rejected, Accpet queue Length is 3, larger than Backlog1 1, while in the Windows environment C4, C5 and C6 will be rejected, the accept queue Length is 2, equals Backlog1. this may be due to a different operating system TCP caused by different parameter settings.

Under different operating systems, the error exception when the connection is rejected is also different. Windows Connnection refused exception, exception location in Socket.connect (* * *), This is because the connection is denied, or there is no connection , while the Linux report connection reset exception, The exception position is in Is.readline () (This exception is usually caused by one end of the socket being closed while the other end is still reading and writing), which is probably due to the server being disconnected more than backlog+1 Connection and the client is still causing the readLine () . This may be caused by different operating systems that are different for TCP implementations.

L in the test process, the client side only set the ConnectionTimeout, not set so_timeout. In the Linux environment, C5 and C6 will be rejected after about 100s, while C4, C5, and C6 in the Windows environment will be rejected immediately. This should have nothing to do with ConnectionTimeout. Because the client does not have so_timeout set, the estimate is not related to this parameter. should be in addition ConnectionTimeout and the So_timeout There is also an operating system default parameter to control Yes 100s or at once, it is unclear.

If So_timeout is set on the client side, for example, 5s, then the behavior on Linux is C2 and its client will wait for its reply 5s after the connection on the server to report read timed out, the exception position in Is.readline () The phenomenon on Windows is that C4 and its subsequent client still immediately report connection refused exceptions, where the exception is in Socket.connect (* * *), while C2 and C3 are on the connection server waiting for its reply 5s after read timed Out exception, exception position in Is.readline ().

If So_timeout is set on the client side, for example, 110s, then the behavior on Linux is C5 and the client after 100s will be reported connection reset exception, the abnormal position in is.readline (), and C2, C3 and C4 will be reported in the 110s after the read timed out exception, the abnormal position in is.readline (); The phenomenon on Windows is C4 and the client after it is still reporting connection refused exception immediately, The exception location is in Socket.connect (* * *), while C2 and C3 are on the connection server waiting for its reply 110s after the read timed out exception, the exception position in Is.readline ().

This is the meaning of the so_timeout parameter. two operating systems the understanding at this point is consistent.

3. Accessories

Code used for testing:

Client.java

1  Packagesocket;2 3 ImportJava.io.*;4 Importjava.net.*;5 Importjava.util.Date;6 7  Public classClient {8 9     /**Ten      * @paramargs One      */ A      Public Static voidMain (string[] args) { -         //TODO auto-generated Method Stub -         Try { theSystem.out.println (NewDate ()); -InetAddress remoteaddress = Inetaddress.getbyname ("127.0.0.1"); - //inetaddress localaddress = Inetaddress.getbyname ("127.0.0.1"); - //SOCKET socket = new socket (remoteaddress, 1287, localaddress, 1288); + //SOCKET socket = new socket (remoteaddress, 1287); -Socket socket =NewSocket (); +Socket.connect (NewInetsocketaddress (remoteaddress,1287), 1000); ASocket.setsotimeout (5000); atSystem.out.println (NewDate ()); -PrintWriter OS =NewPrintWriter (Socket.getoutputstream ()); -BufferedReader is =NewBufferedReader (NewInputStreamReader (Socket.getinputstream ())); -String msg = "Hello"; - os.println (msg); - Os.flush (); inSystem.out.println ("Client:" +msg); - //Thread.Sleep (+); toSystem.out.println ("Server:" +is.readline ()); +System.out.println (NewDate ()); -Thread.Sleep (1000000); theSystem.out.println ("end!"); * os.close (); $ is.close ();Panax Notoginseng socket.close (); -}Catch(unknownhostexception e) { the             //TODO auto-generated Catch block +System.out.println (NewDate ()); A e.printstacktrace (); the}Catch(IOException e) { +             //TODO auto-generated Catch block -System.out.println (NewDate ()); $ e.printstacktrace (); $         } -         Catch(interruptedexception e) { -             //TODO auto-generated Catch block theSystem.out.println (NewDate ()); - e.printstacktrace ();Wuyi         } the          -     } Wu  -}

Server.java

1  Packagesocket;2 3 ImportJava.io.*;4 Importjava.net.*;5 6  Public classServer {7 8     /**9      * @paramargsTen      */ One      Public Static voidMain (string[] args) { A         //TODO auto-generated Method Stub -         Try { -ServerSocket ServerSocket =NewServerSocket (1287,2); theSocket socket =serversocket.accept (); -              -PrintWriter OS =NewPrintWriter (Socket.getoutputstream ()); -BufferedReader is =NewBufferedReader (NewInputStreamReader (Socket.getinputstream ())); +              while(true){ -System.out.println ("Client:" +is.readline ()); +String msg = "HI"; A os.println (msg); at Os.flush (); -System.out.println ("Server:" +msg); -             } - //os.close (); - //is.close (); - //socket.close (); in //serversocket.close (); -}Catch(IOException e) { to             //TODO auto-generated Catch block + e.printstacktrace (); -         } the //catch (Interruptedexception e) { * //            //TODO auto-generated Catch block $ //e.printstacktrace ();Panax Notoginseng //        } -  the     } +  A}

About the Java socket

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.