大家好。
我尝试使用Windows套接字发送和接收UDP数据包(用C ++编写)
它运作良好,直到三天前程序停止正常运行
总结一下情况:
(*)我调查了这个错误。在UDP中,这意味着存在ICMP问题。 ("在UDP数据报套接字上,此错误表示先前的发送操作导致ICMP端口无法访问消息。")。
我确实在recvfrom()之前调用了sendto(),所以问题不在这里
我试图放下我的防火墙,看它是否改变了什么,但它没有。我还试图放下流过我电脑的每个网络。在这种状态下,我设法使程序工作了几分钟,但是当我启用网络时它再次停止工作。我试图重复这个过程,但它不再适用了。
我尝试使用visual studio(2015)和MinGW进行编译
我也尝试了另一台计算机(在Windows 7下,我的Windows 8.1),无济于事。
这是一个简单的测试文件,在我的计算机上不起作用。
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x501
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <vector>
#include <iostream>
int main() {
int clientSock;
char buf[100];
int serverPort;
/* Initializing WSA */
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
/* I create my socket */
struct addrinfo specs;
struct addrinfo *addr = new addrinfo;
ZeroMemory(&specs, sizeof(specs));
specs.ai_family = AF_INET;
specs.ai_socktype = SOCK_DGRAM;
specs.ai_flags = 0;
getaddrinfo("127.0.0.1", "2324", &specs, &addr);
clientSock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
/* I get the server's address */
struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddr.sin_port = htons(2324);
int len = sizeof(struct sockaddr);
/* I'll poll & recvfrom on my socket */
std::vector<pollfd> fds;
pollfd fd;
fd.fd = clientSock;
fd.events = POLLRDNORM;
fd.revents = -1;
fds.push_back(fd);
while(1) {
memset(buf,0,sizeof(buf));
printf("\nClient--->: ");
gets(buf);
/* It's UDP, so it doesn't matter if there is someone to receive the packet */
sendto(clientSock, buf, strlen(buf), 0, (sockaddr*)&serverAddr ,len);
memset(buf,0,sizeof(buf));
int ret;
/* Always returns "1" */
if ((ret = WSAPoll(fds.data(), 1, 0)) > 0) {
std::cout << ret;
/* Always returns "-1" */
std::cout << recvfrom(clientSock,buf,sizeof(buf),0, (sockaddr*)&serverAddr,&len) << std::endl;
printf("\n--->From the server: ");
printf("%s",buf);
}
}
closesocket(clientSock);
WSACleanup();
return 0;
}
两个问题:
编辑:我修改了我的主程序(这里没有显示,因为它太大了)只是忽略任何&#34;错误10054&#34;我收到了。现在它的工作方式与在Unix上的工作方式相同
不过,它实际上并不是一个解决方案(忽略错误代码...... meh),如果有人知道为什么我会得到&#34; ICMP Port Unreachable&#34;在致电sendto()
时出错,我很高兴听到这个消息。
答案 0 :(得分:4)
在Windows中,如果主机A使用UDP套接字并调用 float t, tincr;
t = 0;
tincr = 2 * M_PI * 440.0 / c->sample_rate;
for(i=0; i<2000; i++) {
for(j=0;j<frame_size;j++) {
samples[2*j] = (int)(sin(t) * 10000);
samples[2*j+1] = samples[2*j];
t += tincr;
}
/* encode the samples */
向主机B发送内容,但B不绑定任何端口,以便B不接收消息,然后主持A呼叫{ {1}}要收到一些消息,sendto()
将失败,recvfrom()
将返回recvfrom()
。
这是Windows的一个错误。如果UDP套接字在发送消息后收到ICMP(端口不可达)消息,则会存储此错误,下次调用WSAGetLastError()
将返回此错误。
有两种方法可以解决这个问题:
10054
答案 1 :(得分:0)
我已经删除了Authors代码,并包含了Simmerlee的修复程序。这提供了一种更简单的方法来重现该错误:
#include "stdafx.h"
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)
void testCase(bool fixed)
{
int clientSock;
char rcvBuf[100];
// create socket
clientSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(fixed)
{
BOOL bNewBehavior = FALSE;
DWORD dwBytesReturned = 0;
WSAIoctl(clientSock, SIO_UDP_CONNRESET, &bNewBehavior, sizeof bNewBehavior, NULL, 0, &dwBytesReturned, NULL, NULL);
}
// bind socket
struct sockaddr_in clientAddr;
clientAddr.sin_family = AF_INET;
clientAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
clientAddr.sin_port = htons(61234);
int sizeClientAddr = sizeof(clientAddr);
bind(clientSock, (sockaddr*) &clientAddr, sizeClientAddr);
struct sockaddr_in serverAddr = clientAddr;
serverAddr.sin_port = htons(2324); // change port where nobody listens
int sizeServerAddr = sizeof(struct sockaddr);
int lasterror = 0;
int status = 0;
// send where nobody is listening
printf("Send to nowhere--->:\n");
/* It's UDP, so it doesn't matter if there is someone to receive the packet */
status =sendto(clientSock, "Message", 7, 0, (sockaddr*)&serverAddr, sizeServerAddr);
lasterror = WSAGetLastError();
printf("sendto return %d (lasterror %d)\n", status, lasterror);
// recvfrom with "failing" sendto before.
// fixed: This should block.
// unfixed: WSAGetLastError is 10054
memset(rcvBuf, 0, sizeof(rcvBuf));
status = recvfrom(clientSock, rcvBuf, sizeof(rcvBuf), 0, (sockaddr*)&serverAddr, &sizeServerAddr);
lasterror = WSAGetLastError();
printf("recvfrom return %d (lasterror %d)\n", status, lasterror);
printf("--->From the server: -%s-\n", rcvBuf);
closesocket(clientSock);
}
int _tmain(int argc, _TCHAR* argv[])
{
/* Initializing WSA */
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
printf("##### UNFIXED\n");
testCase(false);
printf("##### FIXED\n");
testCase(true);
WSACleanup();
// pause
char buf[100];
gets(buf);
return 0;
}
这应该返回:
##### UNFIXED
Send to nowhere--->:
sendto return 7 (lasterror 0)
recvfrom return -1 (lasterror 10054)
--->From the server: --
##### FIXED
Send to nowhere--->:
sendto return 7 (lasterror 0)
然后阻止。