我有两个系统,都运行Windows 7。源是192.168.0.87,目标是192.168.0.22,它们都连接到我办公桌上的一个小交换机上。
源正在使用此程序向目标传输100个UDP数据包的突发-
#include <iostream>
#include <vector>
using namespace std;
#include <winsock2.h>
int main()
{
// It's windows, we need this.
WSAData wsaData;
int wres = WSAStartup(MAKEWORD(2,2), &wsaData);
if (wres != 0) { exit(1); }
SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) { exit(1); }
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(0);
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { exit(3); }
int max = 100;
// build all the packets to send
typedef vector<unsigned char> ByteArray;
vector<ByteArray> v;
v.reserve(max);
for(int i=0;i<max;i++) {
ByteArray bytes(150+(i%25), 'a'+(i%26));
v.push_back(bytes);
}
// send all the packets out, one right after the other.
addr.sin_addr.s_addr = htonl(0xC0A80016);// 192.168.0.22
addr.sin_port = htons(24105);
for(int i=0;i<max;++i) {
if (sendto(s, (const char *)v[i].data(), v[i].size(), 0,
(struct sockaddr *)&addr, sizeof(addr)) < 0) {
cout << "i: " << i << " error: " << errno;
}
}
closesocket(s);
cout << "Complete!" << endl;
}现在,在第一次运行时,我得到了UDP数据包的大量丢失(通常只有1个包可以通过!)。在随后的运行中,所有100个都通过了。如果我等待2分钟左右,再运行一次,我又会丢失大部分数据包。
目标系统上的接收是使用Wireshark完成的。我还在源系统上同时运行了Wireshark,并且在所有情况下都发现了与目标系统上完全相同的跟踪。
这意味着数据包在源机器上丢失,而不是在交换机或线路上丢失。
我还尝试运行sysinternals进程监视器,发现确实,所有100个sendto调用都会产生适当的winsock调用,但不一定是网络上的数据包。
据我所知(使用arp -a),在所有情况下,目标的IP都在源的arp缓存中。
谁能告诉我为什么Windows在处理这些数据包的方式上如此不一致?在我的实际应用程序中,我只是对我的发送进行了一些速率限制,但我想了解为什么它有时会起作用,而不是其他时候。
哦,是的,我还尝试将系统替换为发送和接收,但行为没有任何变化。
发布于 2014-01-25 05:37:37
最有可能的情况是,客户端正在溢出udp发送缓冲区。可能是在ARP协议正在运行以获取目标MAC地址时。你说你在第一次运行时就丢失了数据报,如果你等待2分钟或更长时间。为什么你不和Wireshark确认一下在第一次运行中发生了什么?(如果发送/接收ARP帧)
如果这就是问题所在,您可以应用以下两种方法之一:
1-在运行之前,请确保ARP条目已存在。
2-发送第一个数据报,等待1秒或更短时间,发送突发
https://stackoverflow.com/questions/21342267
复制相似问题