1

C99 クライアントが Java サーバーと通信できるようにしようとしています。ただし、Java サーバーが受信するデータは、送信されたデータと同じではありません。(例: @x�@Ófl/ú.��@¨���������������Û¢ÁBp'ˇ¡`Ôfl/)

エンコーディングの問題だと考えましたが、レンガの壁にぶつかりました。2 つのプログラムをテストして、Java サーバーは Java クライアントと通信でき、C クライアントは C サーバーと通信できると結論付けました。

ただし、Java サーバーが C クライアントと通信することはできません。

Java コード:

serverSocket = new ServerSocket(port);  
Socket sock = serverSocket.accept();                               

BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));

String inputString = in.readLine();
System.out.println(inputString);

C コード:

struct sockaddr_in sin;
struct hostent *host;

host = gethostbyname(hostname);

bzero(&(sin.sin_zero),8); 
sin.sin_port = htons(port);
sin.sin_addr = *((struct in_addr *)host->h_addr);
sin.sin_family = AF_INET;

sock = socket(AF_INET, SOCK_STREAM, 0);

if(connect(sock, (struct sockaddr *)&sin,sizeof(struct sockaddr_in)) == -1)

...

send(sock, &message, strlen(message)+1, 0);

編集: 2 つのホスト間で「TEST」という単語を送信しようとしましたが、成功しませんでした。

修正済み: メッセージ変数を渡すときに、メッセージ変数の前にアンパサンドがありました。

になるはずだった:

send(sock, message, strlen(message)+1, 0);
4

4 に答える 4

2

C99 がエンコーディングの標準を提供しているかどうかはわかりませんが、実装固有のものだと思います。それはUS-ASCII例えばあるかもしれません。

何が起こるかというと、Java InputStreamReader(または出力) は、OS または Java インストール (場所がわからない) のどこかで指定されたデフォルトの文字セットを使用するため、C プログラムで使用されるものとは異なる場合があります。

あなたができる最善のことは、さまざまなエンコーディングをテストすることです.InputStreamReaderクラスは実際に特定のコンストラクタを提供します:

public InputStreamReader(InputStream in, Charset cs)

使用する文字セットを指定できます。可能な文字セットについては、こちらをご覧ください。

于 2012-05-24T04:13:31.317 に答える
1

また、エンディアンの不一致も確認する必要があります。Javaはネットワーク順序を使用しますが、Cホストは使用しない場合があります。、ここByteBufferに示されているように、役立つ場合があります。

于 2012-05-24T04:15:49.460 に答える
1

私が間違っていなければ、あなたは次のようなものを持っています:

char *message = "Hello";

送信する場合:

send(sock, &message, strlen(message)+1, 0);
           |
           +---- Err.

メッセージ自体ではなくメッセージのアドレスを送信し、さらに長さをメッセージの長さに設定し、そのようなゴミをパディングします。

代わりにこれを行う場合:

send(sock, message, strlen(message)+1, 0);

それはうまくいくはずです。

またはchar message[] = "Hello";…を使用します</p>


サーバーデータをさらに分析するには、次のようにします。

        int i = 0;
        for (char ch : inputString.toCharArray()) {
            System.out.printf("%2d: 0x%02X o%03o %3d %c%n",
                i++,
                (int)ch & 0xff,
                (int)ch & 0xff,
                (int)ch & 0xff,
                Character.isISOControl(ch) ? '.' : ch
            );
        }

また

        buf = inputLine.getBytes(/* charset  */);
        for (i = 0; i < buf.length; ++i) {

Client siad: Hello
 0: 0x00 o000   0 .
 1: 0x48 o110  72 H
 2: 0x65 o145 101 e
 3: 0x6C o154 108 l
 4: 0x6C o154 108 l
 5: 0x6F o157 111 o

メッセージの使用(&M):

Client said: `�
 0: 0x60 o140  96 `
 1: 0xEF o357 239 ￯
 2: 0xBF o277 191 ﾿
 3: 0xBD o275 189 ᄑ
 4: 0x04 o004   4 .
 5: 0x08 o010   8 .

別のハック/デバッグ/できることは次のようなものです:

    while (true) {
        in.mark(128);
        if ((inputLine = in.readLine()) == null)
            continue;

        System.out.println("Response: " + inputLine);

        in.reset();
        i = 0;
        while (in.ready()) {
            c = in.read();
            System.out.printf("%2d: 0x%02X o%03o %3d %c%n",
                i++,
                c, c, c,
                Character.isISOControl((char) c) ? '.' : (char)c
            );
        }
    }
于 2012-05-24T06:23:09.727 に答える
0

あなたの問題はバイトアラインメントのように見えます

クライアントでは、ホストをネットワークバイトオーダーCに変換する必要があります。

使用する

uint32_t htonl(uint32_t hostlong);

uint16_t htons(uint16_t hostshort);

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort);
于 2012-05-24T04:17:53.793 に答える