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

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

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

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

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

ネットワーク

ネットワークとは、複数のコンピューター間を接続する技術です。インターネットが最も主流なネットワークの形態で、TCP/IP・HTTP・DNSなどの様々なプロトコルや、ルータやサーバーなどの様々な機器の上に成り立っています。

Q&A

解決済

3回答

16308閲覧

udp での多重クライアント用サーバ

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

ネットワーク

ネットワークとは、複数のコンピューター間を接続する技術です。インターネットが最も主流なネットワークの形態で、TCP/IP・HTTP・DNSなどの様々なプロトコルや、ルータやサーバーなどの様々な機器の上に成り立っています。

1グッド

2クリップ

投稿2016/02/13 19:36

UDPを用いた通信を受け付ける多重クライアントサーバの実装方法がわかりません.
UDPはアクセプトがないためデータグラムはおくりっぱなしだと思います.
そこでその多重化にはpollかthreadかselectか...

と思ったのですが,クライアントを識別しながら多重クライアント用のサーバを作るにはどのようにしたらいいのでしょうか?

考えたのが
サーバサイドにクライアントを格納する双方向リストを作成し,headerを送信する際にユーザ識別子を降って識別
新規ユーザからのコネクションは新たにクライアントを追加...

という手順ですがpollを使おうとしたのですが,実装方法がわかりません..申し訳ありません.
どなたかアドバイスお願いいたします.
poll で 3つの場合分けをしたのですが,case0 ,case1,default
そのうちdefault にrecvfrom()を書き,クライアント多重の処理をすればいいのかなと思っています.

ai_2013_dev👍を押しています

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

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

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

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

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

kozuchi

2016/02/14 01:14

ここでいう「多重クライアントサーバ」というのは、「複数のクライアントと同時に通信するサーバ」という意味でいいのでしょうか?
退会済みユーザー

退会済みユーザー

2016/02/14 03:31

そうです、言葉足らずで申し訳ありません。
guest

回答3

0

ベストアンサー

こんにちは。

少し話が混乱しているように感じます。
UDPサーバも普通に複数のクライアントからの要求を処理できますよ。
ご存知のようにTCPとの大きな違いの1つとしてコネクションを張らないことがありますね。

これが何を意味するかと言うと、TCPは同一のクライアントとコネクションを張ることで「継続」して通信できます。しかし、UDPはコネクションの概念がないので同一のクライアントから受信した時、それを以前に受け付けた要求と関連付けることができないことです。つまり、単発の処理要求に応答する部分までしかプロトコル・スタックがサポートしていないと言うことです。

もし、同一のクライアントからの「継続」した要求であることを認識する必要があるのであれば、アプリ側でクライアントのIPアドレスとポート番号を使って同一のクライアントを判別することが考えられます。きちんとコネクション接続と切断をアプリ側のプロトコルで取り決めて「コネクション」を管理すれば問題ないのではないでしょうか? ここまでなら、ユーザ識別子=クライアントのIPアドレス+ポート番号とし、recvしたバケットのそれらに応じて当該クライアント向けの継続処理し、終わったらrecv待ちすればよいと思います。

次に、その継続処理に時間がかかる場合はサブ・スレッドにて処理するのが一般的と思います。(C10Kのようなケースを除く)その場合に、当初のポートと同じポートを使い続ける方法と、クライアント毎にサーバ側で別途ポートを開く方法が考えられます。前者はかなり面倒なので私なら後者を使います。
C10K問題を考慮しない限り、どちらの場合でもrecvで十分と思います。

前者ならrecv後、そのクライアント用に処理をしているスレッドへ何らかのスレッド間通信で処理依頼するか、スレッド・プールのスレッドを使ってその処理を依頼後、直ぐにrecv継続ですね。結構面倒です。
後者ならメインのポートをrecvしているスレッドでコネクション要求を処理し、要求があったらサブ・スレッドを起動して処理を依頼後、直ぐにrecv継続です。サブ・スレッドはコネクション接続処理の残り(自分用のソケット生成含む)~コネクション切断(自分用のソケット破棄含む)まで担うイメージです。

投稿2016/02/14 04:45

編集2016/02/14 05:34
Chironian

総合スコア23272

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

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

退会済みユーザー

退会済みユーザー

2016/02/14 09:04

回答ありがとうございます。 疑問なんですが、同時リクエストが発生した場合にrecvで受け取った内容が上書きされる可能性はないのですか? 例えばrecvfrom でbufに値を格納したとして、その値が次の受信のせいで上書きされてしまうのではないかと思いました。 pollを使ってi/o多重化しているのですが....
Chironian

2016/02/14 13:06 編集

> 同時リクエストが発生した場合にrecvで受け取った内容が上書きされる可能性はないのですか? バグ等を除けば可能性はないと思います。 プロトコル・スタックはrecv等で渡されるのとは別にデータ受信用に内部バッファを持っています。それが一杯になるまでは受信できます。そしてその内部バッファが一杯になったらパケットを破棄している筈です。流石に受信済データへ勝手に上書きなんてされたら、通信制御できませんし。 recv等はその受信バッファのデータを指定のバッファへコピーして持ってくるものです。そして、指定サイズに不足していたら受信待ちになります。 1つのスレッドで複数のソケットの受信待ちしたい時、pollやselectを使います。 複数のソケットの受信を1つのスレッドで処理したいのに直接recvしてしまった場合、そちらのソケットにデータが届かず、recvしていないソケットへどんどんデータが届くと内部の受信バッファがオーバーフローしちゃいますね。 そこで、pollなどで指定の複数のソケットのどれかにデータが溜まるのを待ち、溜まったソケットからrecvするわけです。
guest

0

正直申し上げますと、ご質問の内容だけでは、
あなたの求めるサーバーをどのように実装すればいいのかは私にもわかりません。

  • どのように多重化するか
  • クライアントをどう識別するか
  • ポーリングをどのように実装すべきか

いずれの問題も、提供しようとするサービスの内容によって最適解は変わってきます。
そもそも UDP をつかうべきかどうかも、サービスの内容や性能要件などによって決まってくるものです。
全部ブロードキャストにしてまったくホストを識別しない、ということもサービスによってはありえます。
ポーリングでは非効率なので select ベースにすべき場合もあれば、簡易化のためにポーリングで済ます場合もありえます。
それはサービスの内容と要件を考慮して決めることで、そういう前提抜きに一概にこうするのがいい、
と言える性質の問題ではありません。

順番としては、サービスを決め、アプリケーション層のプロトコルを決め、
それからやっと UDP 等のトラスポート層のプロトコルを真剣に設計することになると思います。
(実際にはアプリケーション層のプロトコルとトランスポート層のプロトコルの設計はかなり
同時進行することになると思いますが)
アプリケーションによってはネゴシエーションはデータグラムベースでやって、
本体の通信はコネクションベースという設計もありえます。
サービスの内容がわからないのにただ UDP を使うとだけ言われてもどうするほうがいいのかのアドバイスはしようがありません。

投稿2016/02/14 14:12

kozuchi

総合スコア1193

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

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

0

UDPは、コネクションレスですから、サーバ側の受信ポートは不特定のクライアントからの送信を待つだけです。複数のクライアントから受信することはできますが、サーバとクライアント間の関係(コネクション)の管理は独自に開発したプログラムで行うしかないです。そのためTCP/IPのように、複数のクライアントの通信を並行的に行う事は不可能です。
もちろんUDPを使ってTCPと同様にコネクション管理、送達確認などなどを行うプログラムを開発することは可能ですが、それなら素直にTCPを使ったほうが開発工数がはるかに少なくて済むと思います。

何かUDPでなければならない理由があるなら、それを説明することで適切な回答が得られるかも知れません。

投稿2016/02/14 04:05

coco_bauer

総合スコア6915

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問