Java network programming from getting started to mastering: Socket class getter and Setter methods (2)

Source: Internet
Author: User

Second, used to get and set Socket Options for Getter and the Setter Method

The socket selection lets you specify how the socket class sends and accepts data. In JDK1.4 there are 8 socket options that can be set. All 8 of these options are defined in the Java.net.SocketOptions interface. Defined as follows:

Public final static int tcp_nodelay = 0x0001;
Public final static int so_reuseaddr = 0x04;
Public final static int so_linger = 0x0080;
Public final static int so_timeout = 0x1006;
Public final static int so_sndbuf = 0x1001;
Public final static int so_rcvbuf = 0x1002;
Public final static int so_keepalive = 0x0008;
Public final static int so_oobinline = 0x1003;

Interestingly, these 8 options are prefixed with so in addition to the first one not in the so prefix. In fact, this is the acronym for Socket option, so in Java, all constants prefixed with so are represented by the socket option, and of course there are exceptions, such as Tcp_nodelay. A pair of get and set methods are provided for each option in the socket class, respectively, to obtain and set these options.

1. Tcp_nodelay

public Boolean Gettcpnodelay () throws socketexception public void Settcpnodelay (Boolean on) throws SocketException

By default, when a client sends data to the server, it determines whether to send it immediately, depending on the size of the packet. When the data in the packet is very small, such as only 1 bytes, and the packet header has dozens of bytes (IP header +tcp header), the system will be sent before sending the smaller package into a soft packet, together with the data sent out. When the next packet is sent, the system waits for the server to respond to the previous packet, and when it receives the response from the server, it sends the next packet, which is called the Nagle algorithm; By default, the Nagle algorithm is turned on.

Although this algorithm can effectively improve the efficiency of network transmission, but for the network speed is relatively slow, and the implementation of the high requirements of the situation (such as games, Telnet, etc.), the use of this method to transmit data will make the client has a noticeable pause phenomenon. Therefore, the best solution is to use it when the Nagle algorithm is needed and close it when it is not needed. And the use of Settcptodelay just can meet this demand. When the Nagle algorithm is closed with Settcpnodelay (true), the client sends the data every time it is sent, regardless of the packet size.

2. so_reuseaddr

public Boolean getreuseaddress () throws socketexception public void Setreuseaddress (Boolean on) throws Socketex Ception

This option allows you to bind multiple socket objects on the same port. This does not make much sense, but when you close the socket connection using the Close method, the port that the socket object is bound to is not necessarily released at once, and sometimes the socket connection is closed to confirm that there are packets that have not arrived because of the delayed surface, which is completely handled at the bottom. This means that it is transparent to the user, so it is not felt at all when using the socket class.

This processing mechanism has no effect on the socket object of the randomly bound port, but may throw an "Address already in Use:jvm_bind" exception for the socket object bound on the fixed port. Therefore, this option can be used to avoid the occurrence of an exception.

PackageMyNet;
Import java.net.*; Import java.io.*;
public class test {    public static void main (String[] args)      {        socket socket1 = new socket () ;         socket socket2 = new socket ();         try         {             socket1.setreuseaddress (TRUE);             socket1.bind (new  Inetsocketaddress ("127.0.0.1",  88));             system.out.println (" Socket1.getreuseaddress (): "                     + socket1.getreuseaddress ());           &nbsP; socket2.bind (new inetsocketaddress ("127.0.0.1",  88));                  catch  ( Exception e)         {             system.out.println ("Error:"  + e.getmessage ());             try              {                 socket2.setreuseaddress (TRUE);                 socket2.bind ( New inetsocketaddress ("127.0.0.1",  88));                  System.out.println ("Socket2.getreuseaddress ():"                         +  socket2.getreuseaddress ());                  SYSTEM.OUT.PRINTLN ("Port 88 second bind succeeded!");             }              catch  (EXCEPTION E1)              {                 system.out.println (E.getmessage ());             }          }     }}

The result of the above code is as follows:

Socket1.getreuseaddress (): True error:address already in Use:jvm_bind socket2.getreuseaddress (): True port 88 second bind succeeded!

There are two points to note when using the SO_REUSEADDR option: 1. You must use the Setreuseaddress method to open the SO_REUSEADDR option before calling the Bind method. Therefore, to use the SO_REUSEADDR option, you cannot bind a port by using the socket class's construction method. 2. The SO_REUSEADDR option for all socket objects that are bound to the same port must be turned on to work. As in routine 4-12, both Socket1 and Socket2 use the Setreuseaddress method to turn on their so_reuseaddr options.

3. So_linger

public int Getsolinger () throws socketexception public void Setsolinger (Boolean on, int linger) throws SocketException

This socket option can affect the behavior of the Close method. By default, when the Close method is called, it is returned immediately, and if there are still packets that are not sent, the packets are discarded. If the linger parameter is set to a positive integer n (the maximum value of n is 65,535), the Close method will be blocked for up to n seconds after it is called. In this n seconds, the system will try to send the data that is not sent out, if it exceeds n seconds, if there are packets packets, the packets will be discarded, and the Close method will return immediately. If you set linger to 0, the effect of the So_linger option is the same.

The socketexception exception will be thrown if the underlying socket implementation does not support So_linger. Setsolinger also throws an IllegalArgumentException exception when a negative value is passed to the linger parameter. The Getsolinger method can be used to get the delay time off, and if 1 is returned, the So_linger is closed. For example, the following code sets the delay-off time to 1 minutes:

if (socket.getsolinger () = =-1) Socket.setsolinger (true, 60);

4. So_timeout

public int getsotimeout () throws socketexception public void setsotimeout (int timeout) throws SocketException

This socket option has been discussed earlier. This option allows you to set the read data timeout. When the Read method of the input stream is blocked, if timeout is set (the unit of timeout is milliseconds), then the system throws a interruptedioexception exception after waiting for a timeout millisecond. After the exception is thrown, the input stream is not closed and you can continue reading the data through the Read method.

If you set timeout to 0, it means that read will wait indefinitely until the server program closes the socket. This is also the default value for timeout. The read data timeout is set to 30 seconds, as in the following statement:

Socket1.setsotimeout (30 * 1000);

These two methods will throw socketexception exceptions when the underlying socket implementation does not support the So_timeout option. You cannot set timeout to a negative number, otherwise the Setsotimeout method throws an IllegalArgumentException exception.

5. So_sndbuf

public int getsendbuffersize () throws socketexception public void setsendbuffersize (int size) throws SocketException

By default, the send buffer for the output stream is 8,096 bytes (8K). This value is the size of the output buffer recommended by Java. If this default value does not meet the requirements, you can use the Setsendbuffersize method to reset the buffer size. However, it is best not to set the output buffer too small, or it will cause the transmission of data too frequently, thereby reducing the efficiency of network transmission.

If the underlying socket implementation does not support the SO_SENDBUF option, these two methods will throw the SocketException exception. Size must be set to a positive integer, otherwise the Setsendbufferedsize method throws an IllegalArgumentException exception.

6. So_rcvbuf

public int getreceivebuffersize () throws socketexception public void setreceivebuffersize (int size) throws SocketException

By default, the receive buffer for the input stream is 8,096 bytes (8K). This value is the size of the input buffer recommended by Java. If this default value does not meet the requirements, you can use the Setreceivebuffersize method to reset the buffer size. However, it is best not to set the input buffer too small, or it will result in the transmission of data too frequently, thereby reducing the efficiency of network transmission.

If the underlying socket implementation does not support the SO_RCVBUF option, these two methods will throw the SocketException exception. Size must be set to a positive integer, otherwise the Setreceivebuffersize method throws an IllegalArgumentException exception.

7. So_keepalive

public Boolean getkeepalive () throws socketexception public void Setkeepalive (Boolean on) throws SocketException

If this socket option is turned on, the client socket will send a packet to the server using an idle connection for a period of approximately two hours. This packet has no other effect, just to detect if the server is still active. If the server does not respond to this packet, after approximately 11 minutes, the client socket sends another packet, and if the server is not responding within 12 minutes, the client socket will be closed. If the socket option is turned off, the client socket may not shut down for a long time if the server is invalid. The so_keepalive option is turned off by default, and you can use the following statement to turn this so_keepalive option on:

Socket1.setkeepalive (TRUE);

8. So_oobinline

public Boolean getoobinline () throws socketexception public void Setoobinline (Boolean on) throws SocketException

If this socket option is turned on, a single-byte data can be sent to the server via the Sendurgentdata method of the socket class. This single-byte data does not go through the output buffer, but is emitted immediately. Although the client does not use OutputStream to send data to the server, the single-byte data in the service-side program is mixed with other common data. As a result, it is not known in the service-side program whether the data sent by the client is OutputStream or sent over by Sendurgentdata. The following is a declaration of the Sendurgentdata method:

public void Sendurgentdata (int data) throws IOException

Although the Sendurgentdata parameter data is of type int, only the low byte of the int type is sent, and the other three bytes are ignored. The following code demonstrates how to use the So_oobinline option to send single-byte data.

PackageMyNet;
Import java.net.*; Import java.io.*;
Class server {    public static void main (String[] args)  throws  exception     {        ServerSocket  Serversocket = new serversocket (1234);         SYSTEM.OUT.PRINTLN ("Server has been started, port number: 1234");         while  (True)          {            Socket socket =  Serversocket.accept ();             socket.setoobinline (TRUE);             InputStream in =  Socket.getinputstream ();             inputstreamreader inreader =  new inputstreamreader (in);             bufferedreader breader = new  BufferedReader (Inreader);             system.out.println (BReader.readLine ()) ;             system.out.println (BReader.readLine ()) ;             socket.close ();         }     } public class client {    public static void main (String[] args)  throws  exception     {        socket socket  = new socket ("127.0.0.1",  1234);         socket.setoobinline (TRUE);         outputstream out = socket.getoutputstream ();         OutputStreamWriter outWriter = new  OutputStreamWriter (out);         outwriter.write (;       )        //  send the character "C" to the server          Outwriter.write ("hello world\r\n");         socket.sendurgentdata (;      )   //  send the character "A" to the server   &nbSp;     socket.sendurgentdata (322);         //   sends the character "B"         outwriter.flush () to the server;         socket.sendurgentdata (214);        //  send Chinese characters "        socket.sendurgentdata" to the server (208);         socket.sendurgentdata (185);        //  Send the Chinese character "country"         socket.sendurgentdata (250) to the server;         socket.close ();     }}

Since running the above code requires a server class, in addition to a server class named server, the usage of the service end socket will be discussed in detail in a later article. Only the Accept method of the ServerSocket class is used in the Class Server class to receive requests from clients. And reads two lines of string from the data from the client and displays it on the console.

Test

Because this example uses 127.0.0.1, the server and client classes must be running on the same machine.

Running the server

Java mynet. Server

Run Client

Java mynet. Client

Output from the console of the server

Server already started, port number: 1234 Abchello World China

The Sendurgentdata method was used in the client class to send the characters ' A ' (65) and ' B ' (66) to the server. But sending ' B ' actually sends 322, because Sendurgentdata only sends a low byte of the integer number. Therefore, the actual transmission is 66. Decimal integer 322 is shown in binary form 1.

Figure 1 Binary form of decimal integer 322

As can be seen from Figure 1, although 322 is distributed on two bytes, its low byte is still 66.

Use flush in the client class to send data from the buffer to the server. We can find a problem from the output result, in the client class has sent to the server "C", "Hello World" R "N", "A", "B". Abchello World is displayed on the console of the service-side program. This behavior indicates that the system will send the data immediately after the data is sent using the Sendurgentdata method, and using write to send the data, you must use the Flush method to actually send the data.

Sends a "Chinese" string to the server in the client class. Since "Zhong" is made up of 214 and 2,082 bytes, and "State" is made up of 185 and 2,502 bytes, it is possible to send these four bytes separately to transmit the "China" string.

Note: When you use the Setoobinline method to open the So_oobinline option, be aware that this option must be turned on both the client and server side programs using the Setoobinline method. Otherwise, you cannot name the Sendurgentdata to send the data.

Java network programming from getting started to mastering: Socket class getter and Setter methods (2)

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.