Проблемы с отправкой кириллических сообщений через сокет

Я пытаюсь отправить кириллические сообщения через сокет, и у меня проблема. Сообщение не проходит.
Если я использую символ (с обеих сторон), то с другой стороны получаю, что кириллица неверна.
Если я использую 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: куб.см

ТЕСТОВОЕ ЗАДАНИЕ «!» СООБЩЕНИЕ

0

Решение

Исходя из того, что вы разместили, трудно сказать, что не так.

Прежде всего, обычная проблема, recv / send может нет дать вам данные, которые вы просили, так как это всего лишь подсказка. Что еще более запутывает, что на локальном хосте это происходит почти всегда, а это означает, что send, скорее всего, отправит данные за один вызов, а recv получит их за один вызов.

Взгляни на RECV а также Отправить особенно раздел замечаний о буфере и его длине.

Во-вторых, строки обычно плохо себя ведут при отправке по сети, при условии, что серверная часть также является Windows, она может работать, но все же, вы должны всегда отправлять сообщения на основе количества символов * размер символа для ASCII размер символа равен 1 байт для юникода, это 2 байта для окон но Linux использовал 4 байта, поэтому вы должны убедиться, что знаете, какова длина вашей строки, а затем рассчитать ее размер в байтах. Вдобавок ко всему этому вы должны убедиться, что знаете, где заканчиваются ваши данные, как для функций отправки, так и для отображения строк, которые обычно равны ‘\ 0’, но вы можете сообщить сетевой функции, как долго она на самом деле находится. до отправляя строковые данные, и когда данные записываются, вы вручную ставите нулевое значение ‘\ 0’ в конце.

Таким образом, в зависимости от того, что вы опубликовали, оно должно работать, потому что C автоматически добавляет \ 0 в конце каждой статической строки, и поскольку вы запускаете это на локальном хосте, send / recv также должен работать, так что у вас либо проблема с сетью, либо что-то еще неправильно. Опубликуйте больше информации, если можете, так как трудно из этого сказать, что может быть не так.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector