免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6070 | 回复: 8

[C] 如何设置socket发送完数据后再关闭socket [复制链接]

论坛徽章:
1
15-16赛季CBA联赛之深圳
日期:2016-02-17 16:12:23
发表于 2014-01-28 14:13 |显示全部楼层
本帖最后由 lewy7 于 2014-01-29 14:23 编辑

一socket服务端,write数据到socket的时候(数据长度2KB,且该socket是非阻塞的),然后就直接close(socket_fd)了,

导致客户端read的时候发生Connection reset by peer(客户端单进程,1%的概率发生,数据越大发生概率就越大,但数据长度小于1KB的时候就没有这种情况)

服务端socket未设置setsockopt(SO_LINGER)或者(SO_DONTLINGER)。



后来试了一下服务端对需要write的socket用SO_LINGER,也无效

贴代码:

for  epoll_wait{
     if  fd ==  listenfd
             accept;   setnonblock(clientfd);  EPOLLIN&& EPOLL_CTL_ADD;
     if  EPOLLIN|EPOLLET
             read;     EPOLLOUT&&EPOLL_CTL_MOD;
     if  EPOLLOUT|EPOLLET
             write;     EPOLL_CTL_DEL ;  close(fd);
}

请问一下这个情况应该怎么修改服务端?

论坛徽章:
0
发表于 2014-01-28 14:36 |显示全部楼层
    struct linger tmp = { 0, 0 };
    ret = setsockopt( sockfd, SOL_SOCKET, SO_LINGER, &tmp, sizeof( tmp ) );

论坛徽章:
1
15-16赛季CBA联赛之深圳
日期:2016-02-17 16:12:23
发表于 2014-01-28 21:50 |显示全部楼层
回复 2# wenlq


   这个试过了,但报错了:illegal seek。

  但相同的代码,我拿到另一台机子(ubuntu)上去就没有发现有这样的问题(Connection reset by peer)。先前的那台机子是(RHEL5),是不是系统参数的问题?


Speed=19084 Requests/min, 648890 bytes/sec.
Requests: 19084 susceed, 0 failed.

论坛徽章:
4
双子座
日期:2014-08-28 10:08:002015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:58:112015年亚洲杯之阿联酋
日期:2015-03-13 03:25:15
发表于 2014-01-29 09:03 |显示全部楼层
so_linger一般是请求方用的, server端一般不主动调用close函数,除非异常。

so_linger是说请求方发送完了,直接发一个RST的包,而不是FIN的包关闭连接

至于server那边,你开门做生意还能主动赶客户吗?所以一般不主动关,除非被攻击,或者异常

论坛徽章:
1
15-16赛季CBA联赛之深圳
日期:2016-02-17 16:12:23
发表于 2014-01-29 12:08 |显示全部楼层
回复 4# weishuo1999


   
weishuo1999 发表于 2014-01-29 09:03
so_linger一般是请求方用的, server端一般不主动调用close函数,除非异常。

so_linger是说请求方发送完 ...



发送完毕后不主动关,要是客户端也不关的话,这个socket不也会一直开着的吗?

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
发表于 2014-01-29 13:25 |显示全部楼层
回复 5# lewy7
当然一直开着~~
但是别人也只能一直开着啊~~
你要担心这个问题,
可以设一个很大的数值,
但Socket数大于这个数值时,
按最久未使用顺序,
给它们发测试包,
如果错误则关之~

   

论坛徽章:
1
15-16赛季CBA联赛之深圳
日期:2016-02-17 16:12:23
发表于 2014-01-29 15:04 |显示全部楼层
回复 6# folklore


    看来是我设计有问题,当初就不应该想着靠write一次能发这么多数据出去,什么MTU啊,buf啊都有可能限制一次发送的数据长度,而又因为这个socket是非阻塞的,所以就报了这样的错,犯了这样的罪。

  谢谢以上各位的帮助{:3_203:}

论坛徽章:
1
白羊座
日期:2013-09-18 22:02:26
发表于 2014-02-04 23:53 |显示全部楼层
看看poll或select对tcp的ack是否管用。

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:032015年亚洲杯之中国
日期:2015-04-22 15:52:45
发表于 2014-02-05 17:52 |显示全部楼层
这是经典TCP短连接的问题啊.
你每次send后, 判断一下返回值是否OK.
不觉得send后close会有什么问题.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP