【发布时间】:2017-11-20 01:18:08
【问题描述】:
我正在使用 C++ 开发一个 UDP 套接字,它既是客户端又是服务器。我正在使用 Visual Studio 2017 并在 Windows 7 上运行它。recvfrom() 函数有一些问题,以“无效参数”错误结尾。我认为套接字没问题,sockaddr_in 结构没问题,线程没问题,甚至带有 sendto() 函数的 while 循环也没问题。但是调用recvfrom()函数后线程就结束了,我真的不知道问题出在哪里……
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <thread>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
void printMessage(SOCKET s, SOCKADDR_IN destAddr) {
char message[100];
int result, error;
int addrSize = sizeof(destAddr);
do {
printf("som v threade\n");
result = recvfrom(s, message, 100, 0, (SOCKADDR*)&destAddr, &addrSize);
printf("%d\n", result);
if (result < 0) {
error = WSAGetLastError();
printf("%d\n", error);
}
if (result > 0)
printf("%s", message);
} while (result > 0);
}
int main(int argc, char *argv[]) {
WORD dllVersion = MAKEWORD(2, 1);
WSADATA wsaData;
if (WSAStartup(dllVersion, &wsaData) != 0) {
printf("Winsock startup failed");
exit(1);
}
const char *ip = "127.0.0.1";
int dstPort = 49999;
int srcPort = 49999;
SOCKADDR_IN destaddr, srcaddr;
SOCKET s;
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s < 0) {
printf("Error creating socket");
exit(1);
}
destaddr.sin_family = AF_INET;
destaddr.sin_addr.s_addr = inet_addr(ip);
destaddr.sin_port = htons(dstPort);
srcaddr.sin_family = AF_INET;
srcaddr.sin_addr.s_addr = htonl(INADDR_ANY);
srcaddr.sin_port = htons(srcPort);
bind(s, (SOCKADDR*)&srcaddr, sizeof(srcaddr));
thread receiving (printMessage, s, destaddr);
receiving.detach();
while (1) {
char message[100];
printf("Write a message:");
scanf("%s", message);
if (sendto(s, message, sizeof(message), 0, (SOCKADDR *) &destaddr, sizeof(destaddr)) < 0) {
printf("Message not sent");
exit(1);
}
}
return 0;
}
【问题讨论】:
-
你没有在检查错误
bind()。您应该在调用printf()或任何其他系统调用之前调用WSAGetLastError()之前,并且每次循环时都应该重新初始化addrSize。 -
并且循环直到接收计数为零是徒劳的,除非您知道 (a) 对等方将发送一个长度为零的数据包以终止发送并且 (b) 它没有被重新排序在你不知道的数据报之前。
标签: c++ sockets udp visual-studio-2017 winsock2