首页 > 解决方案 > recvfrom 在线程中使用时没有给出正确的发件人地址

问题描述

我正在学习 C++ 中的基本套接字编程。我注意到,当recvfrom()从单独的线程调用该函数时,没有正确接收到发件人地址。

这是我的server.cpp文件,只有主线程:

void receive(int sockfd) {

  char buffer[1024];
  int n;
  socklen_t len;

  struct sockaddr_in cliaddr;
  memset(&cliaddr, 0, sizeof(cliaddr));

  n = recvfrom(sockfd, (char *)buffer, 1024,
              MSG_WAITALL, ( struct sockaddr *) &cliaddr,
              &len);
  buffer[n] = '\0';
  printf("Received from client : %s\n", buffer);
  printf("s_addr : %d, sin_port: %d\n", cliaddr.sin_addr.s_addr, cliaddr.sin_port);

}

// Driver code
int main() {
    int sockfd;
    struct sockaddr_in servaddr;

    // Creating socket file descriptor
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    // Filling server information
    servaddr.sin_family    = AF_INET; // IPv4
    servaddr.sin_addr.s_addr = 16777343;
    servaddr.sin_port = 63786;

    // Bind the socket with the server address
    if ( bind(sockfd, (const struct sockaddr *)&servaddr,
            sizeof(servaddr)) < 0 )
    {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    receive(sockfd);

    return 0;
}

产生的输出是:

Received from client : Hello from client
s_addr : 16777343, sin_port: 37261

但是,当函数从不同的线程执行时:

std::thread t(receive, sockfd);
t.join();

输出变为:

Received from client : Hello from client
s_addr : 0, sin_port: 0

这意味着没有正确收到发件人地址。

任何想法?请注意,当我尝试从线程内部创建和绑定套接字时,结果是相同的。

标签: multithreadingsocketsudp

解决方案


ssize_t recvfrom(int sockfd, void *restrict buf, size_t len, int flags,
                    struct sockaddr *restrict src_addr,
                    socklen_t *restrict addrlen);

在调用之前,应将 addrlen 初始化为与 src_addr 关联的缓冲区的大小。

因此,您需要通过以下方式解决此问题:

socklen_t len = sizeof(sockaddr_in);

推荐阅读