2011-12-22 26 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ですか?おそらくあなたはそのようなタグを付けたいでしょうか?どのような場合でも、wiresharkのようなツールを使用して実際にワイヤに何が見えるのかを知り、どのプログラムを最初に見るかを知ることは有益です。 – PlasmaHH

+0

それはUTF-8のためかもしれないが、私はASCIIを試してみるだろう –

答えて

2

さまざまなエンコード変換とI/O戦略が混在しています。

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がデフォルトのコードページではありませんのでご注意:あなたは、次の簡易版を試してみる必要があります。 WindowsのコンソールにUnicodeデータを出力するには、他にもいくつかのライブラリ呼び出しが必要です。

2

のrecvがnullで終わる文字列にその宛先バッファをオンにしない非常に良好ではないかもしれません。これは、バッファ内のバイト数を記入していますが、トップ(当然のエラーチェック、と)これを行う必要がある0

を追加していません:

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

また、RECVはないことに注意してください1つのコールで送信されたものが1つのコールで受信されることを保証するものではありません(UDPを使用している場合を除きます)。

+0

私はいつも単純な整数または文字列を送信しても、1回の呼び出しでそれを受信しましたか? UDPとTCPの選択方法は? – pikmin

+0

TCPは一連のバイトを配信し、UDPは一連のパケット(バイトの配列)を配信します。 UDPは組み込みのメッセージ「境界」を提供します(パケットは1つのメッセージとして64Kバイトまでのメッセージです)。TCPでは、アプリケーションレベルでメッセージをストリームに入れる必要がありますメッセージを挿入するか、メッセージ間に0を挿入します)。 TCPは保証された配信です。正しい順序ですべてのバイトを取得するか、接続が失われます。 UDPはパケットをドロップできます。 – Arkadiy

+0

「単純な整数または文字列」を送信する場合、実際には保証はありません。 send()に渡すデータのサイズは小さくなり、1つのrecv()で配信される可能性があります。しかし、それはタイミングとパケットの境界に関するものです。 send()に渡すデータはIPで配送されるパケットに分割され、recv()はこれまでに到着したすべてのパケットからデータを返します。 – Arkadiy

0

あなたはここでしか単一のwchar_tのための部屋を割り当てている:

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

をあなたはまた、文字列sにバッファを割り当てるが、私は同じ問題を抱えているの

0

を使用するように見えることはありません昨夜から。最後に、私のサーバー(C言語で書かれています)でエンコーディングが認識されていないことが分かりました。したがって、私は

someOutputStream.write(someSillyString.getBytes()); 

この道に私のクライアント

someOutputStream.writeUTF(someSillyString); 

に変更し、私もサーバー側で型キャストする必要はありませんでした。