关于SO_LINGER及TCP断开连接

参考文章: http://lenky.info/2013/02/24/socket%E9%80%89%E9%A1%B9%E7%B3%BB%E5%88%97%E4%B9%8Bso_linger/


SO_LINGER选项只对close()起作用,改变在套接口上执行close()函数的默认行为。关于SO_LINGER套接口选项的设置及作用在很多地方都有介绍,如(unix 网络编程 卷1 p172)。
先说一下我在服务器这里遇到的问题,接收完客服端发送完的数据,需要给客户端返回一条信息,虽然不一定保证客服端必须收到,但要尽力而为。(我用的是阻塞的socket)
开始我只是通过对l_onoff和l_linger都设置为非0,然后调用close()。这样无疑是有问题的,至少在。考重启服务器时可能会说端口已被占用。

一种方法使用应用级确认,服务器向客户发送数据后调用read来读取对端应用层发送来的数据。这样无疑保证对端一定能收到(当然不出现网络问题的情况下),然后再close()。但这样又会增加服务器的负担,需要维持一段时间的链接。另一种方法,先调用shutdown,等一段时间在close。这里等一段时间怎样确定呢?sleep()绝对不是好的办法。

最后解决方法(可能不是最好的,希望大牛指点啊):通过结合选项SO_LINGER、函数close()、函数shutdown()、函数read()配合设计。

1) 设置SO_LINGER选项参数l_onof非0而l_linger为0;
2) 调用函数shutdown(sock_fd, SHUT_WR);
3) 设置超时定时器,假定为t秒;
4) 调用函数read(sock_fd)阻塞等待,直到读到EOF或被定时器超时中断。
5) 执行函数close(sock_fd)或者调用exit(0)进程退出。


linger   InternalLinger;
InternalLinger.l_onoff=1;
InternalLinger.l_linger=0;
setsockopt(sfd, SOL_SOCKET, SO_LINGER, (const   char*)&InternalLinger, sizeof(linger));//设置SO_LINGER选项(防范LOSE_WAIT挂住所有套接字)


#denfine TIMEOUT 5;
struct tiemval tv_timeout;


   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值