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

本文详细介绍了SO_LINGER选项在Socket编程中的作用及其不同设置的影响。通过客户端和服务端的示例代码,展示了如何控制Socket关闭时的行为,包括立即关闭、延迟关闭及数据处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.sina.com.cn/s/blog_6b1990eb0101171o.html
1:设置该选项: public void setSoLinger(boolean on, int seconds) throws SocketException;

<wbr><wbr><wbr>读取该选项:public int getSoLinger() throws SocketException</wbr></wbr></wbr>

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

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

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

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

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

<wbr></wbr>

2:类SimpleClient

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

public class SimpleClient {

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

}

<wbr></wbr>

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 {

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

<wbr></wbr>

4:测试方法

<wbr><wbr>(1)先启动SimpleServer进程,再启动SimpleClient进程</wbr></wbr>

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

<wbr><wbr><wbr><wbr><wbr><wbr>所有未发送完的数据丢失</wbr></wbr></wbr></wbr></wbr></wbr>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值