我有一个非常简单的 Winsock2 TCP 客户端——下面是完整的列表——它只会发送一堆字节。但是,它在网络上运行非常缓慢;数据只是涓涓细流。
这是我尝试并发现的(两台 Windows PC 都在同一个 LAN 上):
- 从一台机器到另一台机器运行这个应用程序很慢 - 发送 8MB 需要大约 50 秒。
- 两个不同的服务器——netcat 和一个自定义编写的服务器(就像下面的客户端一样简单)——产生了相同的结果。
- taskmgr 显示几乎没有使用 CPU 和网络。
- 在同一台机器上与服务器一起运行这个应用程序很快 - 发送 8MB 需要大约 1-2 秒。
- 另一个客户端 netcat 工作得很好——发送 20MB 的数据大约需要 7 秒。(我用的是 Cygwin 自带的 nc。)
- 改变缓冲区大小(1*4096、16*4096 和 128*4096)几乎没有区别。
- 在不同 LAN 上的 Linux 机器上运行几乎相同的代码工作得很好。
- 在调用周围添加一堆打印语句
send
表明我们大部分时间都在阻塞它。 - 在服务器端,我们看到一堆 <= 4K 块的接收(不管发送方推送的缓冲区大小)。但是,其他客户端也会发生这种情况,例如全速运行的 netcat。
有任何想法吗?提前感谢您的任何提示。
#include <winsock2.h>
#include <iostream>
using namespace std;
enum { bytecount = 8388608 };
enum { bufsz = 16*4096 };
int main(int argc, TCHAR* argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
struct sockaddr_in sa;
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
sa.sin_port = htons(9898);
sa.sin_addr.s_addr = inet_addr("157.54.144.70");
if (sa.sin_addr.s_addr == -1) {
cerr << "inet_addr: " << WSAGetLastError() << endl;
return 1;
}
char *blob = new char[bufsz];
for (int i = 0; i < bufsz; ++i) blob[i] = (char) i;
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (s == INVALID_SOCKET) {
cerr << "socket: " << WSAGetLastError() << endl;
return 1;
}
int res = connect(s, reinterpret_cast<sockaddr*>(&sa), sizeof sa);
if (res != 0) {
cerr << "connect: " << WSAGetLastError() << endl;
return 1;
}
int sent;
for (int j = 0; j < bytecount; j += sent) {
sent = send(s, blob, bufsz, 0);
if (sent < 0) {
cerr << "send: " << WSAGetLastError() << endl;
return 1;
}
}
closesocket(s);
return 0;
}