質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

1256閲覧

ソケット通信を用いた並行型通信のプログラムについて

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2021/11/24 07:57

編集2021/11/24 08:59

サーバーの並行型通信の課題で、コメント1~4については自分で考えてプログラムを記述するという内容の課題なのですが
正常に動作しませんでした。
Client1(0.0.0) connected
Client1 disconnected
と一度に表示されてしまいます。
つまりメッセージの送受信が出来ない状態です。
何が原因か具体的に教えて欲しいです。
環境はLinuxのターミナルで動かしています。

c

1#include<stdio.h> 2#include<stdlib.h> 3#include<string.h> 4#include<unistd.h> 5#include<sys/socket.h> 6#include<netinet/in.h> 7#include<arpa/inet.h> 8#include<sys/types.h> 9#include<pthread.h> 10 11#define BUFSIZE 1024 12#define LISTENQ 1024 13 14void *thread(void *arg); 15 16struct ThreadArgs{ 17 int sock; 18 int cnt; 19 struct sockaddr_in sa; 20}; 21 22int main(int argc, char *argv[]) 23{ 24 int listen_sock, comm_sock, msg_len, sa_len, cnt; 25 struct sockaddr_in sa, new_sa; 26 pthread_t thread_id; 27 struct ThreadArgs *args; 28 29 listen_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 30 int option = 1; 31 setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); 32 33 memset(&sa, 0, sizeof(sa)); 34 sa.sin_family = AF_INET; 35 sa.sin_port = htons(49152); 36 sa.sin_addr.s_addr = htonl(INADDR_ANY); 37 38 if(bind(listen_sock, (struct sockaddr *)&sa, sizeof(sa)) < 0){ 39 fprintf(stderr, "bind() failure\n"); 40 exit(1); 41 } 42 43 if(listen(listen_sock, LISTENQ) < 0){ 44 fprintf(stderr, "listen() failure\n"); 45 exit(1); 46 } 47 48 cnt = 0; 49 while(1){ 50 printf("Waiting for a client\n"); 51 sa_len = sizeof(new_sa); 52 if((comm_sock = accept(listen_sock, (struct sockaddr *)&new_sa, &sa_len)) < 0){ 53 fprintf(stderr, "accept() failure\n"); 54 exit(1); 55 } 56 ++cnt; 57 58          //1. 引数用の構造体のメモリを確保する 59 args = (struct ThreadArgs *)malloc(sizeof(struct ThreadArgs)); 60 // 61           62 //2.通信用ソケットディスクリプタ、クライアント番号、アドレス構造体を確保した構造体にセット 63 args->sock = listen_sock; 64 args->cnt = cnt; 65 args->sa = sa; 66          //  67 68 //3.pthread_create()でスレッドを作成 69 if (pthread_create(&thread_id, NULL, (void *)thread, (void *)args) != 0){ 70 fprintf(stderr, "malloc() failure\n"); 71 exit(1); 72 } 73 // 74 } 75 return 0; 76} 77 78void *thread(void *arg) 79{ 80 int sock, cnt, n, msg_len; 81 struct sockaddr_in sa; 82 char buf[BUFSIZE]; 83 84 pthread_detach(pthread_self()); 85 86     //4.argから通信用ソケットディスクリプタ、クライアント番号、アドレス構造体を取得し、それぞれsock,cnt,saにセット 87 sock = ((struct ThreadArgs *)arg)->sock; 88 cnt = ((struct ThreadArgs *)arg)->cnt; 89 sa = ((struct ThreadArgs *)arg)->sa; 90 // 91 92 printf("Client %d (%s) connected\n", cnt, inet_ntoa(sa.sin_addr)); 93 94 if((n = recv(sock, buf, sizeof(buf), 0)) > 0){ 95 buf[n] = '\0'; 96 msg_len = strlen(buf); 97 printf("Client %d: %s\n", cnt, buf); 98 if(send(sock, buf, msg_len, 0) != msg_len){ 99 fprintf(stderr, "send() failure\n"); 100 } 101 } 102 close(sock); 103 104 printf("Client %d disconnected\n", cnt); 105 106 free(arg); 107 108}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2021/11/24 08:13

「うまく動きません」を説明してください。 「具合が悪い」の一言で薬をくれる医者はいません。
退会済みユーザー

退会済みユーザー

2021/11/24 08:14

C#は関係ないのでタグを削除してください。
dodox86

2021/11/24 08:21

> 「具合が悪い」の一言で薬をくれる医者はいません。 一見して「これは違うだろう」と処方箋を出してしまいました。ヤブであったかもしれない。 一応想像通りの問題が起きていたのは確認済みですが、それを超えた要望があるのかもしれませんね。
退会済みユーザー

退会済みユーザー

2021/11/24 08:54

修正の依頼ありがとうございます。 あまりに質問が簡潔すぎましたね、すみません。 送受信の操作が出来ずに困っていました。
guest

回答1

0

ベストアンサー

何が原因か具体的に教えて欲しいです。

acceptで返されたソケットディスクリプタを使っていないから、です。

C

1... 2//2.通信用ソケットディスクリプタ、クライアント番号、アドレス構造体を確保した構造体にセット 3//誤: args->sock = listen_sock; 4args->sock = comm_sock; // 正: accept()で返されたものを使う。 5args->cnt = cnt; 6args->sa = sa; 7...

投稿2021/11/24 08:14

dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2021/11/24 08:36

まずはこの回答の修正でTCPクライアントからの送受信はできるはずですが、そもそも > コメント1~4について追加でプログラムを書いたのですが とあるものの、pthreadでスレッド化する前からlisten_socketでは送受信操作できなかったと思うのですが。
jimbe

2021/11/24 08:59

1~4が穴の、穴埋め課題なのではないでしょうか。
退会済みユーザー

退会済みユーザー

2021/11/24 09:02

回答ありがとうございます。 穴埋めでした。 紛らわしくてすみません。 後日動作確認してみます。
退会済みユーザー

退会済みユーザー

2021/11/25 01:21

動作確認しました。 問題なく送受信できました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問