zoukankan      html  css  js  c++  java
  • linux中send函数MSG_NOSIGNAL异常消息

    最近2周在做 ineedle 的国舜项目扩展,需要使用 socket 的 tcp 连接向对方发送消息,当然需求很简单,只是按照对方要求发送指定格式的消息,程序结构也非常的简单,一对多的 client/server 模型,ineedle 发送给多个服务器消息。我们这边在分析出结果,封装为相应格式消息后发送给对方,只需要在线程循环发送消息即可,便在测试环境中编写简单的socket进行模拟消息发送,一对一发送,能够正常发送消息。可以遇到了一个棘手的问题:在服务器端用ctrl+c 来结束服务器接收进程来模拟服务器宕机的情况,结束服务 socket 进程之后,服务端自然关闭进程,可是 client 端也竟然出乎意料的关闭掉。

    这就奇怪了,我在服务端关闭进程,服务器会关闭 tcp 连接,向 client 发送FIN包,client 响应 ack 后,等双向 tcp 连接关闭后,tcp 连接彻底关闭,在 client 端发送消息会失败,返回错误信息,错误消息会被正常的打印出来,可是很多时候错误信息都没有打印( write 函数没有返回),有时候返回了错误信息,但是 client 端进程仍然无辜死掉,我的 client 端可是用的 while(1) 死循环啊,怎么可能。于是乎百度了一番,说法千奇百怪,有说防火墙的问题,关闭防火墙仍然如此。郁闷 ing,测试了其它方法都不行,打印出错误错误码,也没有查询到结果。

    最后问了下我们的张总,问题刚给他说完,他便说他以前也遇到这个问题,给我找到了他以前的解决方案。解决方法是使用 send 函数时候在最后一个参数上加 MSG_NOSIGNAL 标记即可。于是自己更改发送函数 write 为 send 并添加 MSG_NOSIGNAL 标志,重新编译,运行,中断 server,果然这个问题被很潇洒的解决了,感谢张总的英明神武。

    参考一个博文的介绍

    Linux 下当连接断开,还发送数据的时候,不仅 send() 的返回值会有反映,而且还会向系统发送一个异常消息,如果不作处理,系统会出 BrokePipe,程序会退出,这对于服务器提供稳定的服务将造成巨大的灾难。为此,send() 函数的最后一个参数可以设置为 MSG_NOSIGNAL,禁止 send() 函数向系统发送常消息。

  • 相关阅读:
    SQL SERVER 存储过程或触发器等优化SET NOCOUNT ON
    C#以16进制接收串口数据
    DevExpress中的RichEditControl(富文本)控件,如何把滚动条移动至最后!
    DevExpress中XtraReport的XRRichText在打印时,打印不出内容问题
    DevExpress控件GridControl如何在页脚进行汇总
    创建虚拟机SQL server
    接口,抽象类
    Linq 优化
    sql 优化
    C#:Hashtable和Dictionary
  • 原文地址:https://www.cnblogs.com/liwei0526vip/p/5019413.html
Copyright © 2011-2022 走看看