c ++ WINSOCK recvfrom 没有从网络获取数据

c++ WINSOCK recvfrom no get data from network

我有问题,因为我的服务器没有获取 UDP 数据。路由器上的端口被转发,数据收入到本地服务器网络(在嗅探器 (3) 上可见)但服务器不接收它。

Server and server network screen

在连接的sockets上可以看到1和2个TCP数据包正确的收入到服务器。但是我的客户端然后将 UDP 数据发送到服务器并将数据输入到本地服务器网络(请参阅嗅探器在 3 上检测到它)但服务器不接收它。

客户端代码如下:

struct sockaddr_in si_other;
int s, slen = sizeof(si_other);
char buf[10];
char message[10];
WSADATA wsa;

//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
    printf("Failed. Error Code : %d", WSAGetLastError());
    exit(EXIT_FAILURE);
}
printf("Initialised.\n");

//create socket
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
{
    printf("socket() failed with error code : %d", WSAGetLastError());
    exit(EXIT_FAILURE);
}

//setup address structure
memset((char *)&si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(14996);
si_other.sin_addr.S_un.S_addr = inet_addr(server ip);

memcpy(message, "cokolwiek", 8);

//send the message
if (sendto(s, message, strlen(message), 0, (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
    printf("sendto() failed with error code : %d", WSAGetLastError());
    exit(EXIT_FAILURE);
}

但这不是客户端的问题。这是服务器代码,但我认为它也是正确的:

SOCKET s;
struct sockaddr_in server, si_other;
int slen, recv_len;
char buf[10];
WSADATA wsa;

slen = sizeof(si_other);

//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
    printf("Failed. Error Code : %d", WSAGetLastError());
    exit(EXIT_FAILURE);
}
printf("Initialised.\n");

//Create a socket
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
    printf("Could not create socket : %d", WSAGetLastError());
}
printf("Socket created.\n");

//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(14996);

//Bind
if (::bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
    printf("Bind failed with error code : %d", WSAGetLastError());
    exit(EXIT_FAILURE);
}
puts("Bind done");

//blocking on it, waiting for data
if ((recv_len = recvfrom(s, buf, 10, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR)  
{
    printf("recvfrom() failed with error code : %d", WSAGetLastError());
    exit(EXIT_FAILURE);
}

//print details of the client/peer and the data received
printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
printf("Data: %s\n", buf);

一些可能有帮助的描述 - 主服务器循环是 select() 并且当客户端请求命令时,服务器将命令发送回客户端并开始执行命令。

server:
while (1) {
    select()

        if (socket is in FD_SET)
            get data, send it back and handleCommand()
}

handleCommand() {
    tcp data exchange
    wait for udp packet - it fail
}

client:

sendCommand()

//another receiving commands thread
while (recv) {
    handle command
    tcp data exchange 
    send udp data
}

请不要再给我发誓再等一等。我需要为 NAT 穿越打孔。那是什么问题?另一个监听器获取我的数据?但是 netstat -nop UDP -a 没有提供其他正在侦听的信息,并且绑定套接字没有失败。还有另一个重要信息 该代码在程序开始时工作,我的意思是服务器接收数据 但后来没有。

好的,所以 ElderBug

Are you sure you setup the UDP server socket before you send the data ? It's not clear in your question

是的,这是我的错。微秒决定在服务器上设置侦听器之前执行在一台机器上发送数据。谢谢你的回答。

但是我不太明白这个问题。该数据不应该接收缓冲区并通过 recvfrom 函数等待 "grabbing" 它吗?