Linux下send()函数发送数据卡死问题

一. Linux下send()函数,最近在网络通信socket-TCP通信用到。

现象:设备与服务器建立了网络连接后,服务器端写了一个测试程序:在建立了socket连接,与设备网络连接之后,调用close(sock_accept)关闭网络之后,设备端网络接口当运行到Linux系统函数send()函数之后,阻塞状态(卡死现象);

经过反复测试,调试。

解决方法:

ssize_t send(int sock, const void *buf, size_t len, int flags);

Linux下send()函数发送数据卡死问题_第1张图片

调用send()函数时,之前flags为0,flags改为MSG_NOSIGNAL,即

onceSendSize = send(sockfd, buf + onceSendSize, sendSize - onceSendSize, MSG_NOSIGNAL);

改过之后。服务器端与设备建立了网络连接之后,服务器端调用close(sock_accept)关闭网络,设备端网络send()函数不会卡死;

问题终于解决。

二. Linux下send、sendto、sendmsg函数分析

功能描述:
发送消息,send只可用于基于连接的套接字,send 和 write唯一的不同点是标志的存在,当标志为0时,send等同于write。sendto 和 sendmsg既可用于无连接的套接字,也可用于基于连接的套接字。除了套接字设置为非阻塞模式,调用将会阻塞直到数据被发送完。

Linux下send()函数发送数据卡死问题_第2张图片

参数: 

sock:索引将要从其发送数据的套接字。
buf:指向将要发送数据的缓冲区。
len:以上缓冲区的长度。
flags:是以下零个或者多个标志的组合体,可通过or操作连在一起

MSG_DONTROUTE:不要使用网关来发送封包,只发送到直接联网的主机。这个标志主要用于诊断或者路由程序。
MSG_DONTWAIT:操作不会被阻塞。
MSG_EOR:终止一个记录。
MSG_MORE:调用者有更多的数据需要发送。
MSG_NOSIGNAL:当另一端终止连接时,请求在基于流的错误套接字上不要发送SIGPIPE信号。
MSG_OOB:发送out-of-band数据(需要优先处理的数据),同时现行协议必须支持此种操作。

to:指向存放接收端地址的区域,可以为NULL。
tolen:以上内存区的长度,可以为0。

msg:指向存放发送消息头的内存缓冲,结构形态如下

struct msghdr {
    void         *msg_name;     

  socklen_t     msg_namelen;  
    struct iovec *msg_iov;      
    size_t        msg_iovlen;   
    void         *msg_control;  
    socklen_t     msg_controllen;
    int           msg_flags;    
};


可能用到的数据结构有

struct cmsghdr {
    socklen_t cmsg_len;   
    int       cmsg_level; 
    int       cmsg_type;  
  };

返回说明: 
成功执行时,返回已发送的字节数。失败返回-1,errno被设为以下的某个值 
EACCES:对于Unix域套接字,不允许对目标套接字文件进行写,或者路径前驱的一个目录节点不可搜索
EAGAIN,EWOULDBLOCK: 套接字已标记为非阻塞,而发送操作被阻塞
EBADF:sock不是有效的描述词
ECONNRESET:连接被用户重置
EDESTADDRREQ:套接字不处于连接模式,没有指定对端地址
EFAULT:内存空间访问出错
EINTR:操作被信号中断
EINVAL:参数无效
EISCONN:基于连接的套接字已被连接上,同时指定接收对象
EMSGSIZE:消息太大
ENOMEM:内存不足
ENOTCONN:套接字尚未连接,目标没有给出
ENOTSOCK:sock索引的不是套接字
EPIPE:本地连接已关闭

Linux下send()函数发送数据卡死问题_第3张图片

Linux下send()函数发送数据卡死问题_第4张图片

Linux下send()函数发送数据卡死问题_第5张图片

本文参考网址:(谢谢博主分享

Linux下send、sendto、sendmsg函数分析-frankzfz-ChinaUnix博客

你可能感兴趣的:(嵌入式C开发,网络)