gpt4 book ai didi

c++ - 我是否必须在客户端程序中绑定(bind) UDP 套接字才能接收数据? (我总是得到 WSAEINVAL)

转载 作者:IT老高 更新时间:2023-10-28 12:49:40 25 4
gpt4 key购买 nike

我正在通过 Winsock 创建一个 UDP 套接字(AF_INETSOCK_DGRAMIPPROTO_UDP)并尝试 recvfrom在这个套接字上,但它总是返回-1,我得到 WSAEINVAL (10022)。为什么?

当我 bind() 端口时,不会发生这种情况,但我读过绑定(bind)客户端的套接字是很蹩脚的。

我正在向我的服务器发送数据,它会回答,或者至少会尝试。

Inc::STATS CConnection::_RecvData(sockaddr* addr, std::string &strData)
{
int ret; // return code
int len; // length of the data
int fromlen; // sizeof(sockaddr)
char *buffer; // will hold the data
char c;

//recv length of the message
fromlen = sizeof(sockaddr);
ret = recvfrom(m_InSock, &c, 1, 0, addr, &fromlen);
if(ret != 1)
{
#ifdef __MYDEBUG__
std::stringstream ss;
ss << WSAGetLastError();
MessageBox(NULL, ss.str().c_str(), "", MB_ICONERROR | MB_OK);
#endif
return Inc::ERECV;
}
...

这是我刚才写的一个工作示例,它无需在客户端调用 bind() 即可工作:

#pragma comment(lib, "Ws2_32.lib")

#define WIN32_LEAN_AND_MEAN

#include <WS2tcpip.h>
#include <Windows.h>
#include <iostream>

using namespace std;

int main()
{
SOCKET sock;
addrinfo* pAddr;
addrinfo hints;
sockaddr sAddr;
int fromlen;
const char czPort[] = "12345";
const char czAddy[] = "some ip";

WSADATA wsa;
unsigned short usWSAVersion = MAKEWORD(2,2);

char Buffer[22] = "TESTTESTTESTTESTTEST5";
int ret;

//Start WSA
WSAStartup(usWSAVersion, &wsa);

//Create Socket
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

//Resolve host address
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_socktype = SOCK_DGRAM;

if(getaddrinfo(czAddy, czPort, &hints, &pAddr))
{
std::cerr << "Could not resolve address...\n";
std::cin.get();
return 1;
}

//Start Transmission
while(1)
{
ret = sendto(sock, Buffer, sizeof(Buffer), 0, pAddr->ai_addr,
pAddr->ai_addrlen);
if(ret != sizeof(Buffer))
{
std::cerr << "Could not send data\n";
std::cin.get();
return 1;
}

fromlen = sizeof(SOCKADDR);
ret = recvfrom(sock, Buffer, sizeof(Buffer), 0, &sAddr, &fromlen);
if(ret != sizeof(Buffer))
{
std::cout << "Could not receive data - error: " <<
WSAGetLastError() << std::endl;
std::cin.get();
return 1;
}

Buffer[ret-1] = '\0';
std::cout << "Received: " << Buffer << std::endl;
}
return 0;
}

最佳答案

使用 UDP,您必须 bind() 客户端中的套接字,因为 UDP 是无连接的,因此堆栈没有其他方法可以知道将数据报传递给特定端口的程序.

如果您可以在没有 bind() 的情况下 recvfrom(),那么您实际上是在要求堆栈为您的程序提供所有发送到该计算机的 UDP 数据报。由于堆栈仅将数据报传递给一个程序,这会破坏 DNS、Windows 的网络邻居、网络时间同步......

您可能在网上某处读到客户端中的绑定(bind)很糟糕,但该建议仅适用于 TCP 连接。

关于c++ - 我是否必须在客户端程序中绑定(bind) UDP 套接字才能接收数据? (我总是得到 WSAEINVAL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3057029/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com