java网络编程Socket中SO_LINGER选项的用法解读

Posted startFromWeb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java网络编程Socket中SO_LINGER选项的用法解读相关的知识,希望对你有一定的参考价值。

1:设置该选项: public void setSoLinger(boolean on, int seconds) throws SocketException;

     读取该选项:public int getSoLinger() throws SocketException

     SO_LINGER选项用来控制Socket关闭时的行为,默认情况下,执行Socket的close方法,该方法会立即返回,但底层的Socket实际上并不会立即关闭,他会立即延迟一段时间,知道发送完剩余的数据,才会真正的关闭Socket,断开连接。

    setSoLinger(true, 0): 执行该方法,那么执行Socket的close方法,该方法也会立即返回,但底层的Socket也会立即关闭,所有未发送完的剩余数据被丢弃

    setSoLinger(true, 3600): 那么执行Socket的close方法,该方法不会立即返回,而进入阻塞状态,同时,底层的Socket也会尝试发送剩余的数据,只有满足下面的两个条件之一,close方法才会返回:

    (1):底层的Socket已经发送完所有的剩余数据

    (2): 尽管底层的Socket还没有发送完所有的剩余数据,但已经阻塞了3600秒,close()方法的阻塞时间超过3600秒,也会返回,剩余未发送的数据被丢弃。

 

2:类SimpleClient

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class SimpleClient

 public static void main(String[] args) throws UnknownHostException, IOException
  Socket socket = new Socket("localhost", 8000);
  //socket.setSoLinger(true, 0);            //Socket关闭后,底层Socket立即关闭
  //socket.setSoLinger(true, 3600);         //Socket关闭后,底层Socket延迟3600秒再关闭
  OutputStream os = socket.getOutputStream();
  StringBuffer sb = new StringBuffer();
  for(int i = 0; i < 10000; i++)
   sb.append(i);
  
  os.write(sb.toString().getBytes());         //发送一万个字符
  System.out.println("开始关闭Socket");
  long begin = System.currentTimeMillis();
  socket.close();
  long end = System.currentTimeMillis();
  System.out.println("关闭socket所使用的时间为:" + (end - begin) + "ms");
 

 

3:类SimpleServer

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class SimpleServer

 public static void main(String[] args) throws IOException, InterruptedException
    ServerSocket serverSocket = new ServerSocket(8000);
    Socket socket = serverSocket.accept();
    
    Thread.sleep(5000);                   //睡眠5秒钟后再读输入流
    
    InputStream inputStream = socket.getInputStream();
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    byte[] buff = new byte[1024];
    int len = -1;
    do
     len = inputStream.read(buff);
     System.out.println(len);
     if(len != -1)
      buffer.write(buff, 0, len);
    
    while(len != -1);
    System.out.println(new String(buffer.toByteArray()));      //把字节数组转换为字符串
 

 

4:测试方法

   (1)先启动SimpleServer进程,再启动SimpleClient进程

   (2)把 //socket.setSoLinger(true, 0);            //Socket关闭后,底层Socket立即关闭
           的注释去掉,再次先后启动SimpleServer和SimpleClient 进程,这样当Socket关闭时,会强行关闭底层的Socket,

           所有未发送完的数据丢失

   (3)把//socket.setSoLinger(true, 3600);         //Socket关闭后,底层Socket延迟3600秒再关闭
           的注释去掉,再次先后启动SimpleServer和SimpleClient进程,这样当SimpleClient执行Socket的close方法时,

           会进入阻塞状态,直到等待了3600秒,或者底层Socket已经把所有未发送的剩余数据发送完毕,才会从close返回

以上是关于java网络编程Socket中SO_LINGER选项的用法解读的主要内容,如果未能解决你的问题,请参考以下文章

使用SO_LINGER缩短TIME_WAIT的时间,减少大量短链接堆积TIME_WAIT

TCP的选项SO_LINGER设置延时关闭

TCP的选项SO_LINGER设置延时关闭

java中如何创建socket连接的过程?

TCP协议中的SO_LINGER选项

Unix网络编程的实现具体流程