私は非常に単純な Winsock2 TCP クライアントを持っています (完全なリストを以下に示します)。これは単純に大量のバイトを爆破します。ただし、ネットワーク上での実行速度は非常に遅いです。データは少しずつ流れていきます。
これが私が試して見つけたものです(両方のWindows PCが同じLAN上にあります):
- このアプリを 1 台のマシンから別のマシンに実行すると時間がかかります。8 MB を送信するのに ~50 秒かかります。
- 2 つの異なるサーバー (netcat とカスタム作成のサーバー (以下のクライアントと同じくらい単純)) で同じ結果が得られました。
- taskmgr は、CPU とネットワークの両方がほとんど使用されていないことを示しています。
- 同じマシン上のサーバーでこのアプリを実行すると高速です。8MB を送信するのに約 1 ~ 2 秒かかります。
- 別のクライアントである netcat は問題なく動作します。20MB のデータを送信するのに約 7 秒かかります。(Cygwin に付属の nc を使用しました。)
- バッファー サイズ (1*4096、16*4096、および 128*4096) を変更しても、ほとんど違いはありませんでした。
- 別の LAN 上の Linux ボックスでほぼ同じコードを実行すると、問題なく動作しました。
- 呼び出しの周りに一連の print ステートメントを追加すると、
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;
}