以下のコードでは、3つの機能(main
を含む)があります。 receive_loop
関数は127.0.0.1
にバインドされたソケットをポーリングし、メッセージを受け取った場合はそれを出力します。 sender_loop
はscanf
を使用してユーザー入力を待機し、入力がある場合は127.0.0.1
にバインドされたソケットを介して送信します。 main
は、子供にsender_loop
をフォークして実行し、親にはreceive_loop
を実行します。メッセージを受信するメッセージングアプリケーションの1つのインスタンス
コードをコンパイルしてこの実行可能ファイルの2つのインスタンスを実行すると、いずれかのインスタンスが起動するどちらのインスタンスからでも最初に送信されたメッセージが受信されます。つまり、まずinstance1が起動された後、instance1はinstance1とinstance2によって送信されたメッセージを受信します。私はなぜこれが起こっているのか分かりません。誰かがそれを説明できるかどうか分かります(詳細)。ありがとう。
// INCLUDES NOT SHOWN
// recieve_loop
int receive_loop(int sock_fd, struct sockaddr *peer) {
int isDataReady = 0;
char buff[128] = {0};
struct pollfd poll_struct;
poll_struct.fd = sock_fd;
poll_struct.events = POLLIN;
printf("reciever up\n");
while (1) {
while (1) {
if (isDataReady > 0) break;
isDataReady = poll(&poll_struct, 1, 500);
}
socklen_t sock_len = sizeof(struct sockaddr);
recvfrom(sock_fd,
buff,
sizeof(buff),
0,
(struct sockaddr *)peer,
&sock_len);
printf("%s\n", buff);
}
return 0;
}
// sender_loop
int sender_loop(int sock_fd, struct sockaddr *peer) {
char buff[32] = {0};
printf("sender up\n");
while (1) {
scanf("%s", buff);
int bytes_sent = sendto(sock_fd, buff, sizeof(buff), 0, (struct sockaddr *)peer, sizeof(struct sockaddr_in));
if (bytes_sent <= 0)
printf("sending message failed\n");
}
return 0;
}
int main(int argc, const char *argv[]) {
// socket file descriptor to send data through
int sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
// fill in the peer's address, loopback in this case
struct sockaddr_in *peer = malloc(sizeof(struct sockaddr_in));
peer->sin_family = AF_INET;
peer->sin_port = htons(11110);
inet_pton(AF_INET, "127.0.0.1", &peer->sin_addr);
bind(sock_fd, (struct sockaddr *)peer, sizeof(struct sockaddr_in));
pid_t pid = fork();
if (pid < 0) {
printf("Couldn't fork, exiting");
return 1;
}
if (pid == 0) {
sender_loop(sock_fd, (struct sockaddr *)peer);
} else {
receive_loop(sock_fd, (struct sockaddr *)peer);
}
return 0;
}
しかし、なぜ2番目のインスタンスはまだメッセージを送信できますか?それは、メッセージを正しく受け取ったり、受け取ったりすることができないはずです。 – mtahmed
bindを呼び出す前に、setsocktoptでSO_REUSEADDR設定を使用して、バインドが失敗しないようにすることもできます。両方のインスタンスが実行されます。着信パケットが到着すると、インスタンスの1つがパケットを処理します。 SOCK_DGRAM(UDP)では、特定のホストから送信されたパケットが同じプログラムインスタンスによって処理されることは間違いありません。 – selbie
@mtahmed - UDPソケットは特定のポートにバインドされていない場合でも "送信"できます。 OSはソースポートとして使用されていないランダムな値を選択します。 – selbie