2

私は非常に単純な 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;
}
4

3 に答える 3

2

より良い画像を得るためにできることを次に示します。

  • 「接続」、「送信」API 呼び出し内で費やした時間を確認できます。接続呼び出しに問題があるかどうかを確認できます。プロファイラーでそれを行うことができますが、アプリケーションが非常に遅い場合は、デバッグ中にそれを見ることができます.
  • Wireshark (または Ethereal) を実行してネットワーク トラフィックをダンプし、TCP パケットが遅延して転送されることを確認してください。応答が速い場合は、システムのみに関係があります。遅延が見つかった場合は、ルーティング/ネットワークの問題です。
  • "route print" を実行して、PC が宛先マシン (157.54.144.70) にどのようにトラフィックを送信しているかを確認できます。ゲートウェイが使用されているかどうかを確認し、さまざまなルートのルーティングの優先度を確認できます。
  • より小さいチャンクを送信してみてください。(「bufsz」を1024に変更することを意味します)。パフォーマンスとバッファ サイズの間に相関関係はありますか?
  • ウイルス対策、ファイアウォール アプリケーションがインストールされているかどうかを確認しますか? 必ずオフにしてください。ネットワークをサポートするセーフ モードで同じアプリを実行してみることができます。
于 2009-10-23T16:13:45.973 に答える
1

アプリケーションは正常に見えますが、Linuxで正常に動作するとおっしゃいました。これがあなたに役立つかどうかはわかりませんが、私は比較したでしょう-1)Linuxシステムとのウィンドウのmtu値。2)WindowsおよびLinuxでtcp受信メモリサイズを確認しました。3)両方のシステムのネットワークカードの速度が同じであるかどうかを確認しました。

于 2009-10-23T04:18:46.207 に答える