2014-01-09 130 views
0

我試圖通過套接字發送西里爾郵件,我有問題。該消息沒有通過。 如果我使用字符(在兩邊),在我收到的另一邊,cyrilic部分不正確。 如果我使用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

測試「!」 MESSAGE

+0

你是否檢查過發送的數據(例如使用Wireshark)? 然後,您將縮小問題範圍,以查看它是客戶端還是服務器問題。 然後你可以檢查你實際發送,接收的字節,以及如果你的代碼不能停止閱讀某些特殊的東西(比如'\ 0')。 – Maciek

+1

向我們顯示接收方。 – zoska

+0

我已經發布了服務器端和wireshark輸出。對不起,延遲 – nikolakoco

回答

1

根據您發佈的內容很難分辨出什麼是錯的。

首先,通常的問題,收到/發送可能不會給你所要求的數據,因爲它只是一個提示。更令人困惑的是,在本地主機上幾乎所有的時間都能成功發送數據,這意味着發送數據很可能會在一次呼叫中發送數據,而recv會在一次呼叫中收到數據。

看看recvsend,尤其是關於緩衝區和它的長度的註釋部分。

其次,弦一般不表現良好時,通過網絡發送,假設服務器組成部分,也是它可能工作的窗口,但仍然,你必須確保你總是發送基於字符計數*字符ASCII字符大小的大小是1字節的unicode它是2字節的Windows Linux使用4字節,因此你必須確保你知道多久你的字符串,然後計算它的大小以字節爲單位。除此之外,你必須確保你知道你的數據在哪裏結束,發送和字符串顯示函數通常是'\ 0',但是你可以讓網絡函數知道在發送之前實際上有多長時間字符串數據和數據recvd時,然後手動在結尾處輸入空值'\ 0'。

因此,根據你發佈的內容,它應該工作,因爲C會在每個靜態字符串的末尾自動添加一個\ 0,並且由於你在本地主機上運行它,send/recv也應該可以工作,所以你要麼有網絡問題或別的什麼是錯的。如果可以,請發佈更多信息,因爲很難從此告訴可能是錯誤的。

+0

我也發佈了服務器端。基本上我必須要Windows機器,並且我正在嘗試發送消息。 一般的問題是,我有一個更大的問題,我通過包含cyrilic價值的套接字一些html代碼。 – nikolakoco

+0

+1爲'通常的問題'。 – Roddy