【问题标题】:c++ WINSOCK recvfrom no get data from networkc++ WINSOCK recvfrom 没有从网络获取数据
【发布时间】:2016-11-09 11:55:29
【问题描述】:

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

Server and server network screen

您可以看到 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 Traversal 打孔。那是什么问题?另一个监听我的数据?但是 netstat -nop UDP -a 没有给出其他东西正在监听的信息,并且绑定套接字没有失败。还有另一个重要信息该代码在程序开始时工作,我的意思是服务器接收数据但后来没有。

【问题讨论】:

  • 您确定在发送数据之前设置了UDP服务器套接字吗?你的问题不清楚。
  • 警告 你的变量message可能没有很好的初始化:memcpy(message, "cokolwiek", 8);,检查strlen()返回的值
  • @ElderBug 是的,这就是问题所在,谢谢伙计。但是为什么数据没有来到recvbuffer?

标签: c++ sockets networking udp winsock


【解决方案1】:

好吧,就像ElderBug说的那样

您确定在发送数据之前设置了 UDP 服务器套接字吗?你的问题不清楚

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

但我不完全理解这个问题。该数据收入不应该接收缓冲区并等待通过recvfrom函数“抓取”它吗?

【讨论】:

  • 在你设置socket之前,操作系统会收到数据包,但不会有与端口关联的socket,所以数据包会被丢弃。如果你换一种方式理解它会更有意义:存储每个随机数据包而不考虑侦听套接字会很奇怪,更昂贵(并且可能有害)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-25
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
  • 2011-11-02
  • 1970-01-01
相关资源
最近更新 更多