- - PR -
.Net Frameworkのソケット通信のSDKについて初歩的な質問
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-07-03 15:33
こんにちは。
問題作成時には、Q1 ○ Q2 × Q3 ○ Q4 × Q5 ○ と考えてたのですが、 あれこれ調べ直してみると、Q3 については×もありうるような。。。(^^; (問題に不備があるというやつですか) 私の認識(間違いも多々あると思いますが)では、サーバ側で開かれる ポート番号に対しては複数のクライアントから同時接続が可能だと 思っています。 同時に接続要求があった場合、Acceptの処理が済んでいないものに ついては、Listenで確保したキューの中に置かれます。 接続要求は一旦キューに置かれ、Acceptで取り除かれる、という方 が正しいのかも。 (Acceptさせずに、Listenで確保したキューを一杯にした状態で 新たなクライアントから接続しようとすると、接続拒否のエラーが 返ってたような気が。。。) Q3の不備については、 サーバ側で同じポート番号を複数開くことはできない、という認識 だったのですが、『同じプロトコル』ではできないけど 『違うプロトコル』であれば同じポート番号を複数開くことは可能 のようです。 なので、ソケットの接続待ち受けをするプログラムが違うプロトコル で同じポート番号を割り当てる仕組みになっていれば、起動できて しまうということに。。。 | ||||||||
|
投稿日時: 2004-07-03 17:04
諸農です。
純粋に疑問を感じたのですが。
例えば、110番ポートでPOP3をサポートするアプリと SMTPをサポートするアプリの両方が待機できたとして、 110番に接続したクライアントは、どのようにしてPOP3と SMTPの使い分け、または接続したいサーバーサービスの 選択をどのようにすればいいのでしょうか? _________________ 諸農和岳 Powered by Turbo Delphi & Microsoft Visual Studio 2005 十兵衛@わんくま同盟 http://blogs.wankuma.com/jubei/ | ||||||||
|
投稿日時: 2004-07-04 18:39
ここでいうプロトコルは POP3,SMTP といったアプリケーション層のプロトコルではなくて,TCP,UDP といったトランスポート層のプロトコルでは.
| ||||||||
|
投稿日時: 2004-07-05 00:57
あ、なるほど。 1ポートにつきTCPとUDPでそれぞれ1個ずつ(トータルで2個)利用という事ですね。 その意味であれば納得できます。 _________________ 諸農和岳 Powered by Turbo Delphi & Microsoft Visual Studio 2005 十兵衛@わんくま同盟 http://blogs.wankuma.com/jubei/ | ||||||||
|
投稿日時: 2004-07-05 01:13
諸農です。
次の2冊ですが、絵は少なかったですが思った以上にサンプルコードが多く、 同期非同期、ブロッキング、スレッディングについても詳しく書かれていました。 ・C# Network Programming Richard Blum ISBN:0782141765 ・TCP/IP SOCKET IN C# David Makofske ISBN:0124660517 --追加-- 今月(7月3日)発売のドットネットマガジンの 「.NET Frameworkアイデアノート」という連載で 「マルチスレッドTCP/IPサーバーを作る」という表題の 記事が掲載されています。 #投稿した後になにげに雑誌のページをパラパラめくって、 #気付きました。私自身、今から読むところなのですが、 #もしかしたら上記の2冊と同様、参考になるかもしれません。 _________________ 諸農和岳 Powered by Borland Delphi/C++Builder & Microsoft VS.NET [ メッセージ編集済み 編集者: Jubei 編集日時 2004-07-05 01:25 ] | ||||||||
|
投稿日時: 2004-07-05 08:52
たまたま古いデータの入ったHDDが見つかりました。そこに、1999年に作ったシステムのソースがありました。
これで書いた技術報告書もありまして、そこで「マルチタスクだと1秒間に60程度しかプロセスの起動ができない。マルチスレッドだと120のスレッドを起動できた」と書いてあるので、マルチスレッドで行っています。ただし、Solarisです。Windowsだと、70程度で頭打ちになった記憶があります。 システムの概要: サーバは着信を待つ。着信があると、データを受け取り、音声認識ライブラリへデータを引き渡す。音声認識ライブラリからの戻り値を、クライアントに引き渡す。 要求性能は、1時間あたり4万件のデータ処理。音声データの長さ、音声認識ライブラリの性能を考えると、1秒間に112件のデータ処理。 ソース:
注目はacceptです。 if ((clfd = accept(sofd, &cltAddr, &addrlen)) < 0) ここで、sofdは入力引数で、上(C_createSocket関数内)で作ったファイルディスクリプタ(WindowsではSOCKET構造体が相当)を渡します。戻り値は"新しい"ファイルディスクリプタ(WindowsではSOCKET構造体)です。この"新しい"とは、servicesファイル(WindowsXPではSYSTEM32/drivers/etecディレクトリ内)に定義されておらず、現在開いていないポートが使われます(そういうことだったと思う)。 例えば、80番(HTTP)のポートで待っている(accept)とします。ここにクライアント1がアクセスを行います。すると、acceptは、例えば81番のポートにリクエストを複製し、復帰します。すると、クライアント2は80番のポートにリクエストを投げることができます(QooさんのQ1が○)。しかし、復帰する前(複製中など)であるなら、クライアント2の80番に対するリクエストは拒否されます(Q2の×)。複製後、80番のポートは空きますので、次のリクエストはキューに入れられます(2004-07-03 15:33の発言中で言明)。このプログラムでは、スレッド生成後にすぐacceptしますので、キューの先頭がまた複製されます。マルチスレッドや、マルチタスクになっていない場合、acceptが呼ばれるまで、キューにたまり続けます。キューからあふれると、クライアントがエラーを生成します。 私のプログラムに戻って、複製されたポートはargにコピーして、pthread_create関数により、voiceGet関数が新規スレッドとして起動されます。voiceGet関数にて、次の処理を行います。 ソース:voiceGet関数(長いので要所のみ)
このように、複製されたファイルディスクリプタで、クライアントとの通信処理を行っています。このとき、クライアントアプリケーションは、おそらく81番のポートとやりとりをしているとは知りません。クライアントも80番に対して開いて、そのファイルディスクリプタをライブラリから受け取っているので、ポート番号は意識せず、"通信口"に対して処理を行っていると思います。 注意:このプログラムはSolaris用なので、Windowsでは動作しません。 #voiceGetといいながら、判別もやってるし。。。 #命名もめちゃくちゃだし。。。 #そういうツッコミが入れられるということは、成長しているということ、 #と、納得しておこう。。。 | ||||||||
|
投稿日時: 2004-07-05 10:09
半人前です。お世話になっております。
Jubeiさん、レスありがとうございます。
机で小躍りしたのもつかの間、英文ですね(((^^; ですが、ありがとうございます。
とりあえずこっちに飛びつきます(((((^^; | ||||||||
|
投稿日時: 2004-07-05 12:56
自己レスです。
書店に行って斜め読みしたところ、欲しているソケットレベルでの解説ではありません でした・・残念です。 |