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 进行了捕获。这是输出:十六进制:

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:抄送

测试 ”!” 信息

4

1 回答 1

1

根据您发布的内容,很难判断出了什么问题。

首先,通常的问题,recv / send可能不会给你你要求的数据,因为它只是一个提示。更令人困惑的是,在 localhost 上它几乎总是成功,这意味着 send 很可能会在一次调用中发送数据,而 recv 将在一次调用中接收它。

查看recv并特别发送有关缓冲区及其长度的备注部分。

其次,字符串在通过网络发送时通常表现不佳,假设服务器部分也是窗口它可能工作但仍然,您必须确保始终根据字符数发送 * ASCII 字符大小的字符大小是unicode 为 1 字节,windows 为 2 字节,linux 使用 4 字节,因此您必须确保知道您的字符串有多长,然后以字节为单位计算它的大小。最重要的是,你必须确保你知道你的数据在哪里结束,对于发送和字符串显示函数,通常是一个 '\0' 但你可以让网络函数知道它在发送字符串之前实际上是多长时间数据,当数据是 recvd 时,您手动在末尾放置一个 null '\0'。

因此,根据您发布的内容,它应该可以工作,因为 C 会在每个静态字符串的末尾自动添加一个 \0,并且由于您在 localhost 上运行它,发送/接收也应该可以工作,所以您要么有网络问题,要么有其他问题错误的。如果可以的话,请发布更多信息,因为很难从中看出什么是错误的。

于 2014-01-11T22:34:06.463 回答