0

Java と C の間のソケットに問題があります。ソケットを作成してリッスンを開始する C プログラムがあります。Java クライアントは機能し、特定の状況下でソケットを開いて書き込み、読み取りを試みますが、これはブロックされます。

C プログラムのソケット部分は次のとおりです。

int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
char wbuffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
        cout << "ERROR opening socket" << endl;
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 23456;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
int on = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
        cout << "Couldn't set socket params!" << endl;
int so = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
while(so < 0) {
        cout << "ERROR on binding" << endl;
        sleep(1);
        so = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
}
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
        cout << "ERROR on accept" << endl;
bzero(buffer,256);
//cout << "Socket created!" << endl;
n = read(newsockfd,buffer,255);
if (n < 0)
        cout << "Error reading from socket" << endl;
 if (strcmp(buffer, "power\n") == 0) {
         // Do stuff
     strcpy(wbuffer, "off\n");
         }
     //sleep(1);
     n = write(newsockfd,wbuffer,strlen(wbuffer));
     if (n < 0)
         cout << "ERROR writing to socket" << endl;
}
//cout << "message: " << buffer << endl;
close(newsockfd);
close(sockfd);

そして Java 側:

Socket socket3 = new Socket("localhost", 23456);
PrintWriter out3 = new PrintWriter(socket3.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket3.getInputStream()));
out3.write("power" + "\n");
//String status = in.readLine();
log.debug("Wrote power");
StringBuffer buffer = new StringBuffer();
while (true) {
    int ch = in.read();
    log.debug("in.read()");
    if ((ch < 0) || (ch == '\n')) {
        break;
    }
    buffer.append((char) ch);
}
String status = buffer.toString();
out3.close();
in.close();
socket3.close();

書き込みは機能し、デバッグを行いましたが、最後に行われたのは読み取り、特に in.read() です。

C テスト クライアントは出力を適切に読み取るため、Java 側で何かが欠けている可能性があります。

誰かがこれを機能させる方法についていくつかのアイデアを持っていることを願っています。私はどんな解決策にもオープンです。

4

3 に答える 3

2

あなたのC++コードはかなりひどいです。read(2)返品が。未満の場合にどうなるかを検討してください6。そして、ちょうど一般的に:

n = read(newsockfd,buffer,255);

if (n < 0)
    cout << "Error reading from socket" << endl;

// continuing processing after an error - BAD

// not paying attention to n - BAD
if (strcmp(buffer, "power\n") == 0) {
     // Do stuff
     strcpy(wbuffer, "off\n");
}

// potentially writing zero bytes here - BAD
n = write(newsockfd,wbuffer,strlen(wbuffer));

if (n < 0)
     cout << "ERROR writing to socket" << endl;

} // WHERE DID THIS PAREN COME FROM?

したがって、これらの問題を修正してください。ワイヤーで何が得られるかを確認するtcpdump(1)か、wiresharkを使用してください。入力を両面に印刷します。あなたはおそらくあなたの仮定がどこかで外れているのを見るでしょう。

于 2013-01-15T14:03:14.760 に答える
1

問題は実際には読む部分ではなく、書く部分にあったことが判明しました。出力をフラッシュするのを忘れていたので、実際には読み取りを開始していないか、そのために読み取るものがありませんでした。フラッシュを追加した後、読み取りは問題なく機能し、readline() を使用してコードを簡素化することもできました。

ストリームを閉じるときにフラッシュが呼び出されるため、ソケットにのみ書き込みを行った他のケースは機能しませんでした。

C コードは厄介なので、クリーンアップして実際に例外を処理する必要があります。

とにかく私を助けてくれてありがとう、答えがなければ私の間違いを見つけるのにもっと時間がかかったでしょう.

于 2013-01-15T15:01:48.643 に答える
0

多分問題はあなたが整数を読んでいることです:

int ch = in.read()

次のように変更してみましたか:

char ch = in.read()

または、比較する前に整数を char にキャストします。

if((char) ch == '\n' || ch < 0)

今は他に思いつかない…

于 2013-01-15T13:01:17.150 に答える