2011-12-22 4 views
3

Я пытаюсь установить соединение между сервером Java и клиентом C++. Но когда я читаю данные в моем клиенте, у меня всегда такой же странный характер (¬í). Я попытался изменить кодировку в обеих сторонах, но ничего не получилось.Связь сокета между Java и C++

Вот мой Java-код:

public class Serveur 
{ 
    public static void main(String[] args) throws Exception 
    { 
     final int PORT = 13370; 
     try 
     { 
      ServerSocket service= new ServerSocket(PORT); 
      Socket connection = service.accept(); 
      PrintWriter pw = new PrintWriter(connection.getOutputStream()); 
      String s = Integer.toString(5); 
      while(true) 
      { 
       pw.print(s.getBytes("UTF-8")); 
       pw.flush(); 
       pw.close(); 
      } 
      connection.close(); 
     } 
} 

Я также попытался использовать OutputStream, а DataOutputStream и BufferedOutputStream.

А вот C++ код:

int main(int argc, char* argv[]) 
{ 
    WSADATA WSAData; 
    WSAStartup(MAKEWORD(2,0), &WSAData); 
    SOCKET sock; 
    SOCKADDR_IN sin; 
    char buffer[512]; 
    sin.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    sin.sin_family  = AF_INET; 
    sin.sin_port  = htons(13370); 
    sock = socket(AF_INET,SOCK_STREAM,0); 
    if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) 
{ 
    cout<<"connection"<<endl; 
    if(recv(sock, buffer, sizeof(buffer), 0) != SOCKET_ERROR) 
    { 
     string s = buffer; 
     wchar_t *pwchello = L"Hi"; 
     wchar_t *pwc  = (wchar_t *)malloc(sizeof(wchar_t)); 
     char *pmbhello = buffer; 
     int i = mbstowcs(pwc,pmbhello, MB_CUR_MAX); 
     cout << i << endl; 
     cout<<"cout : "<<pwc<<endl; 
     cout <<buffer<<endl; 
     printf("printf : %s\n", buffer); 

     cout << "wsagetlasterror() : "<<WSAGetLastError(); 
     closesocket(sock); 
     WSACleanup(); 
     free(m_pBuffer); 
    } 
    return 0; 
} 

Как вы можете видеть, я попробовал другое решение, но безуспешно.

Заранее спасибо и извините за мой английский это может быть не очень хорошо

+0

Это C или C++? По внешнему виду это C, (например: вы используете 'malloc'). – netcoder

+0

Это winapi? возможно, вы хотите пометить его как таковой? В любом случае для таких вещей полезно знать, как использовать такие инструменты, как wirehark, чтобы вы могли видеть, что на самом деле находится на проводе, чтобы определить, какие из программ будут выглядеть в первую очередь. – PlasmaHH

+0

Возможно, из-за UTF-8, я бы попробовал ASCII –

ответ

2

Вы смешиваете множество различных преобразований кодирования и стратегий ввода-вывода. Вы должны попробовать следующую упрощенную версию:

if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) 
{ 
    cout << "connection" << endl; 

    // the result of 'recv()' is either SOCKET_ERROR or 
    // the number of bytes received. don't though away 
    // the return value. 
    const int result = recv(sock, buffer, sizeof(buffer), 0); 
    if(result != SOCKET_ERROR) 
    { 
     // use length (in bytes) returned by 'recv()' 
     // since buffer is not null terminated. 
     string s(buffer,result); 

     // 's' is in UTF-8 no converstion to wide strings 
     // should be necessary. 
     cout << "message: '" << s << "'." << endl; 
    } 

    closesocket(sock); 
} 
WSACleanup(); 

Однако, обратите внимание, что стандартный вывод находится в текущей кодовой страницы и обычно UTF-8 не кодовая страница по умолчанию. Вывод данных Unicode на консоль в Windows требует нескольких других вызовов библиотеки для настройки.

2

RECV не повернется буфер назначения в строку с нулевым символом. Она заполняет ряд байтов в буфере, но не добавляет 0.

Вам нужно сверху сделать это (с проверкой ошибок, конечно):

ssize_t bytesRead = recv(buffer, ...); 
string str(buffer, bytesRead); 

Кроме того, следует знать, что делает RECV не гарантирует, что что-то, отправленное в одном вызове, будет получено одним звонком (если вы не делаете UDP).

+0

Если я всегда отправляю простое целое число или строку, полученную в один вызов? И как я могу выбрать между UDP и TCP? – pikmin

+0

TCP обеспечивает последовательность байтов, тогда как UDP обеспечивает последовательность пакетов (массивы байтов). UDP предоставляет встроенные «границы» сообщений (пакет представляет собой сообщение, до 64 тыс. Байт, поставляемых как единое целое), тогда как с помощью TCP вам нужно поместить поток в сообщения на уровне приложения (например, обработав каждые 4 байта как единый сообщение или вставка 0 между сообщениями). TCP гарантированная доставка: вы получаете каждый байт в правильной последовательности или теряете соединение. UDP разрешено отбрасывать пакеты. – Arkadiy

+0

Что касается отправки «простого целого или строки», то на самом деле никаких гарантий нет. тем меньше размер данных, которые вы передаете send(), руда, вероятно, будет доставлена ​​в один recv(). Однако речь идет о временных границах и границах пакетов. Данные, которые вы передаете send(), разбиваются на пакеты, которые должны быть доставлены по IP, и recv() будет возвращать данные из всех пакетов, которые были получены до сих пор. – Arkadiy

0

Вы только выделить комнату для одного wchar_t здесь:

wchar_t *pwc = (wchar_t *)malloc(sizeof(wchar_t));

Вы также назначить буфер для строки s, но никогда, кажется, используют S

0

я с той же проблемой с прошлой ночи. Наконец выяснилось, что кодирование не распознается моим сервером (написано на C). Поэтому я изменил в моем клиенте

someOutputStream.writeUTF(someSillyString); 

в

someOutputStream.write(someSillyString.getBytes()); 

Таким образом, я даже не нужно типаж на стороне сервера.

Смежные вопросы