序言
基于udp的socket通信时,linux系统调用recvfrom函数。
-
函数功能如下
- 从套接字上接收一个消息。
- recvfrom :可同时应用于面向连接(TCP)的和无连接(UDP)的套接字。
- recv:一般只用在面向连接(TCP)的套接字,几乎等同于recvfrom,只要将recvfrom的第五个参数设置NULL。
-
存在的问题:阻塞等待超时
- 假如套接字上没有消息可以读取,除非套接字已被设置为非阻塞模式,否则接收recvfrom一直阻塞等待消息的到来。
-
在涉及套接字的I/O操作上设置超时的方法有以下三种:
- 调用alarm。
- 它在指定超时期满时产生SIGALARM。这个方法涉及信号处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm调用。
- 调用select。
- select有内置的时间限制,在select中阻塞等待I/O,以此替代直接阻塞在read或write调用上。
- 调用套接字函数setsockopt
- 使用SO_RECVTIMEO和SO_SNDTIMEO套接字选项
- 调用alarm。
这里介绍比较简单的setsockopt设置超时时间的方法
重点内容
-
示例代码:
/* 设置阻塞超时 */ struct timeval timeOut; timeOut.tv_sec = 5; //设置5s超时 timeOut.tv_usec = 0; if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeOut, sizeof(timeOut)) < 0) { printf("time out setting failed
");
}. . . /* 数据阻塞接收 */ int receivePacketLen = recvfrom(sockfd,buffer,sizeof(buffer),0,(struct sockaddr*)&svr_addr,&addrLen); if (receivePacketLen == -1 && errno == EAGAIN) //阻塞接收超时 { printf("timeout, no input!
");
exit(1);
} -
recvfrom函数返回值
- 成功执行时,返回接收到的字节数。
- 另一端已关闭则返回0。
- 失败返回-1,errno(需添加errno.h头文件)被设为以下的某个值
- EAGAIN:套接字已标记为非阻塞,而接收操作被阻塞或者接收超时
- EBADF:sock不是有效的描述词
- ECONNREFUSE:远程主机阻绝网络连接
- EFAULT:内存空间访问出错
- EINTR:操作被信号中断
- EINVAL:参数无效
- ENOMEM:内存不足
- ENOTCONN:与面向连接关联的套接字尚未被连接上
- ENOTSOCK:sock索引的不是套接字
Acknowledgements:
http://www.cnblogs.com/lidabo/p/3804245.html
http://blog.csdn.net/su_linux/article/details/7057874
http://blog.csdn.net/daiyudong2020/article/details/50675219?locationNum=12&fps=1
http://blog.csdn.net/mingcz/article/details/20814263
2017.07.23