当前位置: 技术问答>linux和unix
Linux下的recvfrom为什么一直阻塞
来源: 互联网 发布时间:2016-11-11
本文导语: 先贴代码 //Client SOCKET UDPSocket = socket(AF_INET, SOCK_DGRAM, 0); sockaddr_in addr; memset(&addr, 0, sizeof(sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = htons(5000); addr.sin_addr.s_addr = INADDR_ANY; bind(UDPSocket, (sockaddr*)&addr, sizeo...
先贴代码
这段代码在Windows上能够正常收发,但如果把Server在Windows上运行,Client在Linux上去收数据就收不到,程序会一直阻塞在recvfrom那里。
我用SmartSniff抓包也能抓到数据,并且已经发送到Linux下的5000端口上了。为什么还是阻塞。
//Client
SOCKET UDPSocket = socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in addr;
memset(&addr, 0, sizeof(sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(5000);
addr.sin_addr.s_addr = INADDR_ANY;
bind(UDPSocket, (sockaddr*)&addr, sizeof(addr));
char buf[1024*8] = {0};
INT len = recvfrom(UDPSocket, buf, 1024*8, 0, NULL, NULL);
//Server
SOCKET serverUDP = socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = 5000;
server.sin_addr.s_addr = INADDR_ANY;
if (SOCKET_ERROR == bind(serverUDP, (sockaddr*)&server, sizeof(server)))
{
INT err = WSAGetLastError();
MessageBox("Error");
}
sockaddr_in clientAddr;
clientAddr.sin_family = AF_INET;
clientAddr.sin_port = htons(5000);
//clientAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //Windows上的本机IP
clientAddr.sin_addr.s_addr = inet_addr("192.168.203.128"); //192.168.203.128是我Linux虚拟机上的IP地址
if (SOCKET_ERROR == sendto(serverUDP, "Hello", 6, 0, (sockaddr*)&clientAddr, sizeof(clientAddr)))
{
MessageBox("Error");
}
这段代码在Windows上能够正常收发,但如果把Server在Windows上运行,Client在Linux上去收数据就收不到,程序会一直阻塞在recvfrom那里。
我用SmartSniff抓包也能抓到数据,并且已经发送到Linux下的5000端口上了。为什么还是阻塞。
|
recvfrom 把参数写全来看看
int len=sizeof(strucgt sockaddr);
recvfrom(UDPSocket, buf, 1024*8, 0, (struct sockaddr *)&their_addr, &len);
看看能不能跑通
int len=sizeof(strucgt sockaddr);
recvfrom(UDPSocket, buf, 1024*8, 0, (struct sockaddr *)&their_addr, &len);
看看能不能跑通
|
UDP的client端是需要bind的,server端不需要bind,
关于阻塞的问题,应该在于你的socket的属性,设置成O_NONBLOCK就可以了。
关于阻塞的问题,应该在于你的socket的属性,设置成O_NONBLOCK就可以了。
|
recvfrom本来就是阻塞,要设置socket属性才可以设置为不阻塞,试试用
int setsockopt (int socket, int level, int optname, void *optval, Function
socklen_t optlen)
This function is used to set the socket option optname at level level for socket socket.
The value of the option is passed in the buer optval of size optlen.
The return value and error codes for setsockopt are the same as for getsockopt.
int setsockopt (int socket, int level, int optname, void *optval, Function
socklen_t optlen)
This function is used to set the socket option optname at level level for socket socket.
The value of the option is passed in the buer optval of size optlen.
The return value and error codes for setsockopt are the same as for getsockopt.
|
linux上用tcpdump查看是否你真的收到服务器发送的包了.
收到了,再定位client的问题
收到了,再定位client的问题