The serversocket class constructor has four reloads. Their definitions are as follows:
Public serversocket () throws ioexception
Public serversocket (INT port) throws ioexception
Public serversocket (INT port, int backlog) throws ioexception
Public serversocket (INT port, int backlog, inetaddress bindaddr) throws ioexception the preceding constructor involves three parameters: Port, backlog, and bindaddr. Specifically, port is the port to be bound to the serversocket object, backlog is the length of the Request queue, and bindaddr is the IP address to be bound to the serversocket object.
1. Bind a port through the constructor
Binding a port through constructor is the most common method for creating a serversocket object. You can bind a port by using the following constructor:
Public serversocket (INT port) throws ioexception if the port specified by the port parameter has been bound, the constructor throws an ioexception. But the exception actually thrown is bindexception. From the inheritance relationship diagram of exception classes in Figure 4.2, we can see that all network-related exceptions are subclasses of the ioexception class. Therefore, ioexception is used to throw other exceptions for the serversocket constructor.
If the port value is 0, the system selects a random port number. However, the randomly selected port is of little significance, because the client needs to clearly know the server when connecting to the server.Program. You can use the tostring method of serversocket to output information related to the serversocket object. The followingCodeEnter information related to the serversocket object.
Serversocket = new serversocket (1320 );
System. Out. println (serversocket); running result:
Serversocket [ADDR = 0.0.0.0/0.0.0.0, Port = 0, localport = 1320] the ADDR in the output result above is the IP address bound to the server. If no IP address is bound, the value is 0.0.0.0, in this case, the serversocket object listens to all IP addresses of all network interfaces on the server. Port is always 0. Localport is the port bound to serversocket. If the port value is 0 (not the output port, it is the parameter port of the serversocket constructor), localport is a randomly selected port number.
1 ~ in the operating system ~ 1023 indicates the port number used by the system. The minimum value of the port number is 1 and the maximum value is 65535. In Windows, you can bind a program with a port number less than 1024, but in Linux/Unix, you must use root login to bind a port less than 1024. PreviousArticleThe socket class is used to determine which ports are opened on the local machine. In fact, the serversocket class can achieve the same purpose. The basic principle is to use serversocket to bind the local port. If a bindexception exception is thrown when a port is bound, it indicates that the port has been opened. Otherwise, the port has not been opened.
Package server;
Import java.net .*;
Public class scanport
{
Public static void main (string [] ARGs)
{
If (ARGs. Length = 0)
Return;
Int minport = 0, maxport = 0;
String ports [] = ARGs [0]. Split ("[-]");
Minport = integer. parseint (ports [0]);
Maxport = (ports. length> 1 )? Integer. parseint (ports [1]): minport;
For (INT Port = minport; port <= maxport; port ++)
Try
{
Serversocket = new serversocket (port );
Serversocket. Close ();
}
Catch (exception E)
{
System. Err. println (E. getclass ());
System. Err. println ("Port" + port + "enabled! ");
}
}
}
In the above Code, the information about the exception class thrown when the serversocket object is created is output. Scanport uses the command line parameter to pass the range of port numbers to be scanned into the program. The parameter format is minport-maxport. If you only enter one port number, the scanport program only scans this port number.
Test
Java Server. scanport 1-1023 running result
Class java.net. bindexception
Port 80 is enabled!
Class java.net. bindexception
Port 135 is enabled! Ii. Set the length of the Request queue
When writing a server program, it generally processes multiple client requests simultaneously through multiple threads. That is to say, a thread is used to receive client requests. When a request is received (a socket object is obtained), a new thread is created and the client request is handed over to the new thread for processing. The thread that receives client requests continues to receive client requests. The implementation code of this process is as follows:
Serversocket = new serversocket (1234); // bind the port
// Code for processing other tasks
While (true)
{
Socket socket = serversocket. Accept (); // wait for receiving client requests
// Code for processing other tasks
New threadclass (socket). Start (); // create and run a thread that processes client requests
} The threadclass class in the code above is a subclass of the thread class. The constructor of this class has a socket-type parameter. You can pass the socket object into the threadclass object through the constructor, and process client requests in the run method of the threadclass object. This code looks like seamless on the surface. No matter how many client requests there are, as long as the server configuration is high enough, it can be processed. However, if you think carefully about the above Code, we may find some problems. If there is enough complex code in lines 2nd and 6th, the execution time is long, which means that the server program cannot respond to the client request in time.
Assume that the code for lines 2nd and 6th is thread. Sleep (3000), which will delay the program for 3 seconds. In these three seconds, the program will not execute the accept method. Therefore, this program only binds the port to 1234 and does not start to receive client requests. If a client sends a request to port 1234 at this time, in theory, the client should have a connection rejection error, but the client shows that the connection is successful. The reason is that the request queue to be discussed in this section is at work.
After a server socket object is bound to a port, the operating system will allocate a first-in-first-out queue for the port (the default queue length is generally 50 ), this queue is used to save unprocessed client requests, so it is called a request queue. The serversocket accept method reads unprocessed client requests from this queue. If the request queue is empty, accept is blocked. Each time a client sends a request to the server, the server first saves the client request in the Request queue, and then reads the accept from the request queue. This can also explain why the above Code can still receive a certain number of client requests without executing the accept method. If the number of client requests in the Request queue reaches the maximum capacity of the Request queue, the server will no longer be able to receive client requests. If the client sends another request to the server, the client will throw a socketexception.
The serversocket class has two constructor Methods: You can use the backlog parameter to reset the length of the Request queue. In the following situations, the maximum length of the Request queue is still limited by the operating system:
• The backlog value is less than or equal to 0.
• The value of backlog is greater than the maximum length of the Request queue defined by the operating system.
• The backlog parameter is not set in the serversocket constructor.
The following area code demonstrates some features of the Request queue. The length of the Request queue is passed in to setrequestqueue through the command line parameter.
Package server;
Import java.net .*;
Class testrequestqueue
{
Public static void main (string [] ARGs) throws exception
{
For (INT I = 0; I <10; I ++)
{
Socket socket = new socket ("localhost", 1234 );
Socket. getoutputstream (). Write (1 );
System. Out. println ("created successfully" + String. valueof (I + 1) + "client connection! ");
}
}
}
Public class setrequestqueue
{
Public static void main (string [] ARGs) throws exception
{
If (ARGs. Length = 0)
Return;
Int queuelength = integer. parseint (ARGs [0]);
Serversocket = new serversocket (1234, queuelength );
System. Out. println ("port (1234) has been bound. Press enter to start processing client requests! ");
System. In. Read ();
Int n = 0;
While (true)
{
System. Out. println ("<prepare to receive" + (++ n) + "client requests! ");
Socket socket = serversocket. Accept ();
System. Out. println ("processing" + N + "client requests ");
Thread. Sleep (3000 );
System. Out. println ("nth" + N + "client requests have been processed!> ");
}
}
}
Test (follow these steps)
1. Execute the following command (do not press the Enter key after executing this command ):
Java Server. setrequestqueue 2
Running result:
Port (1234) has been bound. Please press enter to start processing client requests!
2. Execute the following command:
Java Server. testrequestqueue
Running result:
1st client connections have been created successfully!
2nd client connections have been created successfully!
exception in thread "Main" java.net. socketexception: Connection reset by peer: Socket write error
at java.net. socketoutputstream. socketwrite0 (native method)
at java.net. socketoutputstream. socketwrite (socketoutputstream. java: 92)
at java.net. socketoutputstream. write (socketoutputstream. java: 115)
at server. testrequestqueue. main (setrequestqueue. java: 12)
3. after you press the Enter key to continue executing setrequestqueue, the running result is as follows:
Port (1234) has been bound. Please press enter to start processing client requests!
<Prepare to receive 1st client requests!
Processing 1st client requests
1st client requests have been processed!>
<Prepare to receive 2nd client requests!
Processing 2nd client requests
2nd client requests have been processed!>
<Prepare to receive 3rd client requests! The running result of step 2 shows that when testrequestqueue creates two socket connections, the request queue of the server is full, and the server cannot continue execution for the time being (because of system. in. the execution of the program is suspended for the reason of read (), waiting for user input ). Therefore, the server can no longer receive client requests. At this time, testrequestqueue throws a socketexception. The two socket connections that have been successfully created in testrequestqueue have been saved in the Request queue of the server. Press any key to continue executing setrequestqueue. The accept method reads the two client request queues from the request queue in sequence. The running result of step 3 shows that after the server processes the two requests (one <…> Contains a processing process), the request queue is empty, then the accept processing blocking status, waiting to receive the third client request. If you run testrequestqueue again, how many client requests will the server receive? If we set the length of the Request queue to a value greater than 10, what is the running result of testrequestqueue? You can perform these experiments on your own to see if they are consistent with what you think.
3. bind an IP address
On a computer with multiple network interfaces or IP addresses, you can use the following constructor to bind the server to a specific IP Address:
Public serversocket (INT port, int backlog, inetaddress bindaddr) throws ioexception
The bindaddr parameter is the IP address to bind. If you bind the server to an IP address, only clients that can access this IP address can connect to the server. If a machine has two NICs, one is connected to the Intranet and the other is connected to the Internet. If you use Java to implement an email server and only want Intranet users to use it. You can use this constructor to bind the serversocket object to the IP address connected to the Intranet. In this way, the Internet cannot access the email server. Use the following code to bind an IP Address:
Serversocket = new
Serversocket (1234, 0, inetaddress. getbyname ("192.168.18.10 "));
The above code binds the IP address to 192.168.18.10. Therefore, the server program can only use the network interface bound to this IP address for communication.
Iv. Use of default constructor
In addition to using the serversocket constructor to bind a port, you can also use the bind method of serversocket to complete the work of the constructor. To use the bind method, you must use the default Construction Method of the serversocket class (the construction method without parameters) to create the serversocket object. The bind method has two overload forms. Their definitions are as follows:
Public void BIND (socketaddress endpoint) throws ioexception
Public void BIND (socketaddress endpoint, int backlog) throws ioexception
The bind method can not only bind a port, but also set the length of the Request queue and the bound IP address. The bind method is used to set some options of the serversocket class after the serversocket object is created. These options must be set before the port is bound. Once the port is bound, setting these options will no longer work. The following code demonstrates the use of the BIND method and how to set the serversocket class options.
Serversocket serversocket1 = new serversocket ();
Serversocket1.setreuseaddress (true );
Serversocket1.bind (New inetsocketaddress (1234 ));
Serversocket serversocket2 = new serversocket ();
Serversocket2.setreuseaddress (true );
Serversocket2.bind (New inetsocketaddress ("192.168.18.10", 1234 ));
Serversocket serversocket3 = new serversocket ();
Serversocket3.setreuseaddress (true );
Serversocket3.bind (New inetsocketaddress ("192.168.18.10", 1234), 30 );
The so_reuseaddr option is set in the above Code (this option will be discussed in detail in later articles ). If the following code is used, this option does not work.
Serversocket serversocket3 = new serversocket (1234 );
Serversocket3.setreuseaddress (true); the IP address and port are bound to row 6th. The combination cannot be obtained by using the constructor (backlog parameters must be set to bind IP addresses). Therefore, the bind method is more flexible than the constructor.
this article from the csdn blog, reprinted please indicate the source: http://blog.csdn.net/nokiaguy/archive/2009/07/12/4682952.aspx