multithreading - 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
这意味着没有正确收到发件人地址。
任何想法?请注意,当我尝试从线程内部创建和绑定套接字时,结果是相同的。
解决方案
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);
推荐阅读
- arrays - 算法:从 M 到 N 的最小操作数,只有三个操作
- python - 如何取消以前在numpy中播种的随机序列?
- c# - Xamarin Forms 可绑定对象值更改事件
- react-native - 在 react-native 中创建重叠视图
- android - 相当于 Android Studio 中的 Xcode 目标输出
- python - 在 Python 中将字符串转换为属性
- outlook-addin - 现在是否需要读写权限才能在 Outlook 插件中保存项目的自定义属性?
- bash - 每当将新行写入日志文件时,如何创建一个用于读取和写入的 shell 脚本?
- node.js - SQL SERVER 上的 Node.js 多数据库服务器连接
- php - PHP内存不足试图将sqlsrv查询结果获取到数组