0

サーバーがクライアントからの複数のメッセージを受け入れられない理由を誰かが特定するのを手伝ってもらえますか?

フローを次のようにしようとしています
。1。クライアントがメッセージのサイズをサーバーに送信します
。2。サーバーがサイズを受信して​​応答を送り返します。この場合は0です。3
。クライアントは応答を確認してから、サーバーにメッセージを書き込みます。
4.サーバーはメッセージを読み取り、それを印刷します。

私が得ている問題は、ステップ4のaccept()がブロックを解除しないことです。

クライアント

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main(int argc, char *argv[])
{
int sock = socket(AF_INET, SOCK_STREAM, 0);

struct sockaddr_in s_address;
s_address.sin_family = AF_INET;
s_address.sin_port = htons(51717);
s_address.sin_addr.s_addr = INADDR_ANY;
if (connect(sock, (struct sockaddr *) &s_address, sizeof(s_address)) < 0) {
    printf("ERROR: Cannot connect()\n");
    exit(0);
}

char *org_msg = "Hello";

printf("Writing size of Hello\n");
char msg1[1];
msg1[0] = sizeof(org_msg);
write(sock, msg1, sizeof(msg1));

printf("Waiting for response from server\n");
struct sockaddr_in c_address;
socklen_t c_length = sizeof(c_address);
int new_sock = accept(sock, (struct sockaddr *) &c_address, &c_length);

printf("Reading response from server\n");
char stat[1];
read(new_sock, stat, 1);

if (atoi(stat) == 0) {
    printf("Writing Hello to server\n");
    write(sock, org_msg, sizeof(org_msg));
}
close(sock);
close(new_sock);
}

サーバ

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main(int argc, char *argv[])
{
int sock = socket(AF_INET, SOCK_STREAM, 0);

struct sockaddr_in s_address;
s_address.sin_family = AF_INET;
s_address.sin_port = htons(51717);
s_address.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *) &s_address, sizeof(s_address)) < 0) {
    printf("ERROR: Cannot bind()\n");
    exit(0);
}

listen(sock, 3);

printf("Waiting for client message\n");
struct sockaddr_in c_address;
socklen_t c_length = sizeof(c_address);
int new_sock = accept(sock, (struct sockaddr *) &c_address, &c_length);

printf("Reading client message\n");
char msg[1];
read(new_sock, msg, 1);

printf("Writing response to client\n");
char stat[1];
stat[0] = '0';
write(new_sock, stat, sizeof(stat));

printf("Waiting for client message\n");
int new_sock2 = accept(sock, (struct sockaddr *) &c_address, &c_length);

printf("Reading client message\n");
char msg2[atoi(msg)];
read(new_sock2, msg2, sizeof(msg2));

printf("MESSAGE: %s\n", msg2);

close(sock);
close(new_sock);
close(new_sock2);
}
4

3 に答える 3

3

accept()すでに接続されているソケットを呼び出さないでください。サーバーに接続されたソケット(によって返されるソケットaccept())ができたら、接続が閉じられるまでそのソケットの読み取りと書き込みを続ける必要があります。サーバーの手順は次のようになります。

listen_socket = socket(...);
listen(listen_socket, ...);
connected_socket = accept(listen_socket, ...);
read(connected_socket, ...)
write(connected_socket, ...)
read(connected_socket, ...)
write(connected_socket, ...)
...

同様に、クライアントは、ソケットが正常に接続されたら、ソケットの読み取りと書き込みを続ける必要があります。クライアントの手順は次のとおりです。

connected_socket = socket(...);
connect(connected_socket, ...);
write(connected_socket, ...);
read(connected_socket, ...);
write(connected_socket, ...);
read(connected_socket, ...);
...
于 2012-10-25T20:52:37.400 に答える
1

INADDR_ANYサーバーで動作しますが、クライアントは接続先のホストを指定する必要があります。

両方が同じマシン上にある場合は、127.0.0.1またはlocalhostを使用します(正しい形式になるように変換を行う必要があります)

詳細はこちらですが、簡単な答えは

#define INADDR_LOOPBACK 0x7f000001

その後s_address.sin_addr.s_addr = htonl (INADDR_LOOPBACK)

于 2012-10-25T20:22:37.463 に答える
1

クライアントで、以前にサーバーに接続したソケットとの新しい接続を受け入れようとします。これは、システムが選択したポート番号にバインドされます。サーバーはクライアントへの接続を試行しないため、クライアントへのaccept呼び出しは返されません(実際には、listenそのソケットを呼び出さないため、返される可能性がありますが、エラーが発生します)。

前の手順で使用したのと同じソケットを使用して、手順3を実行してみませんか?何らかの理由で新しいソケットが必要な場合は、以前のソケットを再利用するのではなく、クライアントに新しいソケットを作成する必要があります(またはclose、前のソケットを呼び出しconnectてから、もう一度呼び出します)。

ところで、必要なのがIPCだけの場合、ソケットはそれを行うには本当に悪い方法です。JavaRMIのようなものを提案します。

于 2012-10-25T20:30:49.893 に答える