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

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

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

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

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

Q&A

解決済

2回答

4743閲覧

C言語のソケット通信で、受信と送信を別スレッドで実行したい

blackmailcn

総合スコア9

C

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

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

1グッド

1クリップ

投稿2018/06/12 12:15

前提・実現したいこと

C言語で、ソケット通信処理を書いています。
複数の接続先から接続されるため、ひとつのポートで待ち受け、接続があったら、accept関数の戻り値を引数にしてスレッドを作成して、複数接続先の受信をうけつけるようにしています。
以下のページのような感じです。
http://blog.majide.com/2009/03/thread-echo-server-program/

さらに受信スレッドの他に、送信用のスレッドを立てたいと思っています。
データ送信の必要が出た際、受信スレッドと同じソケット通信を使用して送信スレッドを都度作成し、処理が終わったらスレッドが消えるようなしくみにしたいです。

実際のコードは、ソケットディスクリプタ、送信データ、送信データ長を送信スレッドのパラメータに設定して、send関数を呼んでいます。
send(sockfd, buf, len);

実際にコードを動かしてみたところ、なんとなく動作しているようには見えています。
ただ、送信スレッドにソケットディスクリプタをパラメータで渡しているため、その直前にソケット接続が切断されて、ソケットディスクリプタが無効になってしまう可能性などもあるのかと思っています。

そこでお聞きしたいのは、このようにソケット通信の受信と送信をスレッドでわけるという処理は現実的ではないのか、ということです。
もし他にいい実現方法がありましたら、なにかヒントなどいただけると助かります。
どうぞよろしくお願いいたします。

yohhoy👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

ソケットをcloseするまではディスクリプタは無効にはなりません。有効だけどもはや接続してないので送受信どっちの操作も即座にエラーで帰ってくるようになります。

スレッドプログラミングが一般化する前は送受信を別プロセスで行う事例も普通にありましたから、別に送信と受信を別スレッドで行うのもプログラム設計者がやりたければやればいいんではないでしょうか。しかし、送信1回ごとにスレッドを作っては消すのでしょうか?

投稿2018/06/12 13:15

a_saitoh

総合スコア702

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

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

blackmailcn

2018/06/12 13:27

ご回答ありがとうございます。ディスクリプタは無効にならないのですね! 無効になったディスクリプタを使用してソケット関連関数を呼ぶと、NULLポインタにアクセスしたようになるのかなと勝手に思っていました。 はい。送信1回ごとにスレッドを作成してはデータ送信して終了、を考えていました。送信だけを実行したいタイミングが多くなりそうだったため、送信スレッドを独立して並行処理できれば、という思想でした。
a_saitoh

2018/06/13 00:42

同じディスクリプタを送信スレッドと受信スレッドの両方が操作している場合は、どちらか片方がcloseしてしまって他方が知らないとトラブルになります。そのディスクリプタが新しい通信に割り当てられてしまってるのに気がつかないかもしれないので。一つは「closeは送信スレッドの仕事」とか決めておく.もう一つの対策はdupでディスクリプタを複製して、送信・受信スレッドがそれぞれ別個にcloseするようにすること。
blackmailcn

2018/06/13 14:13

そんなことができるのですね!知りませんでした。Windowsではソケット複製があるんだなと見ていたのですが...。試してみたところとても良さそうです。ありがとうございました!
guest

0

送信だけ別スレッドって、エラーハンドリングやら排他制御やらが面倒になるだけであんましメリットが見えませんが、どーなんでしょう。

私なら接続先ごとにスレッド立てて、そこで送受信を行うように考えますが。

投稿2018/06/12 13:05

y_waiwai

総合スコア87719

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

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

blackmailcn

2018/06/12 13:24

ご回答ありがとうございます。 やはり接続先ごとにスレッドを立てるほうがなんとなく安心な気はしています。 送信だけを実行したいタイミングが多くなりそうだったため、送信スレッドを独立して並行処理できれば、と考えていました。
y_waiwai

2018/06/12 15:05

ふつう、通信というものは、なにかメッセージを送信し、そのレスポンスを受信し、これまたそのレスポンスを送信する、という繰り返しになると思うんで、この送信だけを別スレッドにしても意味はあるのかなあ、というはなしになりますね。 送信したところでその終了を待たないといけないとかなるとスレッドの意味ありませんぜ
blackmailcn

2018/06/12 22:56

ありがとうございます。とりあえず送信スレッドは送りっぱなしで良い前提で、send関数の戻り値だけをチェックできればいいかと考えていましたが、たしかに送信エラーしたときのリトライを待つなどになると、やはり意味がないかもしれませんね。なるほど。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問