UDP进行数据收集,recvfrom函数返回-1,WSAGetLastError() 返回 10060,此时如果打开wireshark,进行数据抓包,代码中recvfrom立马就可以接收到数据了。
(外部有个UDP一直在给本机的9696端口发送数据)
void CSocketTest2Dlg::OnBnClickedOk()
{
//加载socket动态链接库(dll)
WORD wVersionRequested = MAKEWORD( 1, 1 ); // 请求1.1版本的WinSock库
WSADATA wsaData; // 这结构是用于接收Wjndows Socket的结构信息的
int err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
return; // 返回值为零的时候是表示成功申请WSAStartup
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
// 检查这个低字节是不是1,高字节是不是1以确定是否我们所请求的1.1版本
// 否则的话,调用WSACleanup()清除信息,结束函数
WSACleanup( );
return;
}
m_sockClient = INVALID_SOCKET;
// 创建服务端套接字
m_sockClient = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP);// UDP
if( m_sockClient < 0 )
{
closesocket(m_sockClient);
m_sockClient = INVALID_SOCKET;
WSACleanup();
return ;
}
//设置UDP接收缓冲区大小
int rcvbuf_len = 128 * 1024; //实际缓冲区大小的一半。
int len = sizeof(rcvbuf_len);
err = setsockopt( m_sockClient, SOL_SOCKET, SO_RCVBUF, (char *)&rcvbuf_len, len );
if( err < 0 )
{
closesocket(m_sockClient);
m_sockClient = INVALID_SOCKET;
WSACleanup();
return ;
}
struct sockaddr_in sin;
sin.sin_family = AF_INET;
//sin.sin_addr.s_addr = inet_addr("192.168.1.16");
sin.sin_addr.s_addr = htonl(INADDR_ANY); // 本机IP地址
sin.sin_port = htons(9696);
// 绑定套接字,不绑定,系统会自动为套接字指定本机IP地址和随机分配端口号
err = bind( m_sockClient, (struct sockaddr*)&sin, sizeof(sin) );
if ( err != 0 )
{
closesocket(m_sockClient);
m_sockClient = INVALID_SOCKET;
WSACleanup();
return ;
}
u_long ul=0;//1代表非阻塞,0为阻塞
err = ioctlsocket(m_sockClient,FIONBIO,&ul);//设置为阻塞连接
if ( err != 0 )
{
closesocket(m_sockClient);
m_sockClient = INVALID_SOCKET;
WSACleanup();
return ;
}
//设置接收超时
int nNetTimeout = 5000;
err = setsockopt(m_sockClient,SOL_SOCKET, SO_RCVTIMEO, ( char* )&nNetTimeout, sizeof( int ) );
if ( err != 0 )
{
closesocket(m_sockClient);
m_sockClient = INVALID_SOCKET;
WSACleanup();
return ;
}
while(true)
{
int len = 0;
struct sockaddr_in sin;
int nSize = sizeof(sockaddr_in);
BYTE pBuffer[65535];//准备好缓冲区
ZeroMemory(pBuffer,65535);
char* pCurrent = (char*)pBuffer;
TRACE(_T("ReceiveSocketData 2 \n"));
len = recvfrom(m_sockClient, (char*)pCurrent, 65535, 0, (struct sockaddr*)&sin, &nSize);
if(len <= 0)
{
DWORD dwError4 = WSAGetLastError();
TRACE(_T("error = %d\n"), dwError4);
continue;;
}
break;
}
WSACleanup();
}
while循环无法退出,一旦使用wireshark抓包,recvfrom函数就可以正常抓到数据了
不适用wireshar抓包,也可以正常接收到数据