0

ソケットを介してキリル文字のメッセージを送信しようとしていますが、問題があります。メッセージが通りません。(両面で) char を使用すると、受信した反対側で、キリル文字の部分が正しくありません。WCHAR (両側で) を使用すると、最初のキリル文字までメッセージを受け取ります。ASCII 文字のみを送信する場合は、すべて問題ありません。これがクライアントコードです。必要に応じて、サーバー コードも配置できます。

クライアント:

  char ip_addr[] = "192.168.0.102";
  int port = 30000;
  wchar_t message[] = L"TEST ТЕСТ MESSAGE ПОРАКА";
  //char message[] = "TEST ТЕСТ MESSAGE ПОРАКА";
  WSADATA wsaData;
  int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
  if (iResult != 0) {
    wprintf(L"WSAStartup failed: %d\n", iResult);
    return 1;
  }

  struct sockaddr_in messageServer;
  memset(&messageServer, 0, sizeof(messageServer));
  messageServer.sin_family = AF_INET;
  messageServer.sin_addr.S_un.S_addr = inet_addr(ip_addr);
  messageServer.sin_port = htons(port);
  SOCKET outsocket;
  outsocket = socket(AF_INET, SOCK_STREAM, 0);

  if (outsocket == -1) {
    std::cout << "ERROR";
    exit(-1);
  }

  int connRes = 0;
  connRes = connect(outsocket, (struct sockaddr *)&messageServer, sizeof(messageServer));
  if (connRes < 0) {
    std::cout << "ERRROR CONNECT " << WSAGetLastError() <<  std::endl;
    system("pause");
    exit(-1);
  }

  int result;
  result = send(outsocket, (char*)message, sizeof(message), 0);
  if (result == SOCKET_ERROR) {
    wprintf(L"send failed with error: %d\n", WSAGetLastError());
    closesocket(outsocket);
    WSACleanup();
    return 1;
  } else {
    std::wcout << "Return code: " << result << std::endl;
  }
  closesocket(clientSocket);

サーバ:

  int port = 30000;
  char ip_addr[] = "192.168.0.102";
  struct sockaddr_in serverAddr, clientAddr;

  memset(&serverAddr, 0, sizeof(serverAddr));
  memset(&clientAddr, 0, sizeof(clientAddr));

  std::locale::global(std::locale("Russian_Russia"));

  WSADATA wsaData;
  int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
  if (iResult != NO_ERROR) {
    wprintf(L"Error at WSAStartup()\n");
    return 1;
  }

  serverAddr.sin_family = AF_INET;
  serverAddr.sin_addr.S_un.S_addr = inet_addr(ip_addr);
  serverAddr.sin_port = htons(port);

  SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);
  int bindRes = 0;
  bindRes = bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
  if (bindRes < 0) {
    std::wcout << "ERRROR BIND" << WSAGetLastError() <<  std::endl;
    system("pause");
    exit(-1);
  }

  if (listen(serverSocket, 5) < 0)
  {
    std::wcout << "ERRRORRR LISTEN" << std::endl;
    system("pause");
    exit(-1);
  }

  for (;;)
  {
    std::wcout << "WAITING..." << std::endl;
    int length = sizeof(clientAddr);

    wchar_t message[500];
    ZeroMemory(&message, sizeof(message));
    SOCKET clientSocket = accept(serverSocket, (struct sockaddr *) &clientAddr, &length);
    int bR = 0;
    bR = recv(clientSocket, (char*)message, sizeof(message), 0);
    if(bR == -1) {
      std::wcout << "ERRRRORORORORRR";
    }

    std::wcout << "Received bytes: " << bR << std::endl;
    std::wcout << "Message: " << message << std::endl;

    closesocket(clientSocket);
  }

また、Wireshark でキャプチャを作成しました。そして、ここに出力があります: HEX:

54:00:45:00:53:00:54:00:20:00:22:04:15:04:21:04:22:04:20:00:4d:00:45:00:53: 00:53:00:41:00:47:00:45:00:20:00:1f:04:1e:04:20:04:10:04:1a:04:10:04:00:00: cc

テスト "!" メッセージ

4

1 に答える 1

1

あなたが投稿した内容に基づいて、何が間違っているのかを判断するのは難しいです。

まず第一に、よくある問題ですが、recv / sendは、単なるヒントであるため、要求したデータが得られない場合があります。localhost ではほぼ常に成功するということは、send が 1 回の呼び出しでデータを送信し、recv が 1 回の呼び出しでデータを受信する可能性が高いことを意味します。

recvを見て、特にバッファとその長さに関するコメント セクションを送信してください。

第二に、文字列は一般に、ネットワーク経由で送信されるとうまく動作しません.サーバー部分もWindowsであると仮定すると、動作する可能性がありますが、それでも、常に文字数に基づいて送信することを確認する必要があります* ASCII文字サイズの文字サイズはUnicode の場合は 1 バイト、Windows の場合は 2 バイトですが Linux は 4 バイトを使用しているため、文字列の長さを確認してから、サイズをバイト単位で計算する必要があります。これらすべてに加えて、通常は「\ 0」である送信関数と文字列表示関数の両方について、データがどこで終了するかを確認する必要がありますが、ネットワーク関数に文字列を送信するに実際の長さを知らせることができますdata であり、データが recvd の場合、最後に null '\0' を手動で配置します。

したがって、投稿した内容に基づいて、C は各静的文字列の末尾に \0 を自動的に追加するため、機能するはずです。これを localhost で実行すると、send/recv も機能するはずなので、ネットワークに問題があるか、他の何かが違う。これだけでは何が間違っているのかを判断するのは難しいため、可能であれば詳細を投稿してください。

于 2014-01-11T22:34:06.463 に答える