UDP recvfrom始终返回-1
UDP客户端,在主线程初始化,新开一线程循环接收服务器端发来的数据
const char* IP = "127.0.0.1"; ///< 服务器IPUSHORT PORT = 7777; ///< 服务器端口号SOCKET g_sockClient;SOCKADDR_IN g_addrSrv;void main(){ g_RecvData = new _RecvMsgData; g_recv = new char[1024]; WSADATA wsaData; if (WSAStartup(MAKEWORD(2,2), &wsaData)!= NO_ERROR) { return; } if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2) { WSACleanup(); return; } // 创建socket SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0); if (sockClient == INVALID_SOCKET) { WSACleanup(); return; } SOCKADDR_IN addrSrv; // 服务器IP及端口号信息 addrSrv.sin_addr.S_un.S_addr = inet_addr(IP); // 测试时使用本机 addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(PORT); g_sockClient = sockClient; g_addrSrv = addrSrv; unsigned int threadID; unsigned long ret = _beginthreadex(NULL, 0, DataProc, NULL, 0, &threadID); if (ret == 0) // 开辟数据处理线程失败 { AfxMessageBox("开辟数据处理线程失败,退出"); return; }}unsigned int WINAPI __stdcall DataProc(void *pParam){ int len = 0; int ret; unsigned char temp[1024]; int i; while(1) { ret = recvfrom(g_sockClient, g_recv, 1024, 0, (sockaddr*)(&g_addrSrv), &len); if (ret == SOCKET_ERROR) // 网络出错 { int err = WSAGetLastError(); cout<<"WSAGetLastError()="<<err<<endl; return 0; } else { ... } }}#include <stdio.h>#include "winsock2.h"void main() { WSADATA wsaData; SOCKET RecvSocket; sockaddr_in RecvAddr; int Port = 27015; char RecvBuf[1024]; int BufLen = 1024; sockaddr_in SenderAddr; int SenderAddrSize = sizeof(SenderAddr); //----------------------------------------------- // Initialize Winsock WSAStartup(MAKEWORD(2,2), &wsaData); //----------------------------------------------- // Create a receiver socket to receive datagrams RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //----------------------------------------------- // Bind the socket to any address and the specified port. RecvAddr.sin_family = AF_INET; RecvAddr.sin_port = htons(Port); RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); bind(RecvSocket, (SOCKADDR *) &RecvAddr, sizeof(RecvAddr)); //----------------------------------------------- // Call the recvfrom function to receive datagrams // on the bound socket. printf("Receiving datagrams...\n"); recvfrom(RecvSocket, RecvBuf, BufLen, 0, (SOCKADDR *)&SenderAddr, &SenderAddrSize); //----------------------------------------------- // Close the socket when finished receiving datagrams printf("Finished receiving. Closing socket.\n"); closesocket(RecvSocket); //----------------------------------------------- // Clean up and exit. printf("Exiting.\n"); WSACleanup(); return;}
[解决办法]
你首先要搞清楚原理
UDP是无连接的
作为客户端发数据用sendto收数据跟服务端一样都用recvfrom
客户端向服务器端发送一包数据后接下来就可以用recvfrom
来接收服务器端发来的回应,然而你此处并没有向服务器端发送任何数据
那么这个socket的临时通信信道根本就没有建立起来,recvfrom根本无意义
除非你是服务器端等待数据请求
[解决办法]
客户端也要bind,不然别人怎么给你发数据,往哪里发?
[解决办法]
楼主的客户端其实算一个服务器端,需要bind才能收回信息,不然“服务器端”发来的东西,“客户端”也不知道怎么接收。
如果你用tcp,建立了连接,那么客户端可以发送过去,再通过同一个socket接收回来,这样没问题,也不用bind
但udp没有建立这个连接。
[解决办法]
对udp来说,只要你血药接收数据,就要bind。