- PR -

acceptのエラー

投稿者投稿内容
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2005-02-04 12:57
そのサーバがどういうものなのか、まだ分かりません。
同時に複数の接続を受け付けるのか?
受け付けるとするとその方法は? I/Oを多重化しているのか、
あるいは子プロセスにひとつずつ接続を受け持たせているのか?
一度に受け付ける接続はひとつだけなのか?
接続が終了したらどうなるか?サーバ・プロセスはいったん
終了するのか?ループに入って新しい接続を待つのか?
新しい接続を待つときはどうしているか?接続があるかどうか
調べてからaccept()しているのか、ただaccept()して待っている
だけか?
などなど。

仮に、保留状態の接続があることをselect()で判定してから
accept()しているのだとすると、accept()を発行したときには
もう保留されている接続がなくなっていたのだろう、というのが
前々回に書いたことです。
この場合、接続がなくなる理由はふたつ。

ひとつは「別のプロセスが先にaccept()してしまった」
しかし、それならaccept()したヤツがクライアントになにか
返しそうなものです。

もうひとつは「すでに接続が終了していた」
accept()する前にクライアント側から強制切断されていた
場合です。が、いまの問題ではクライアントは待ったままだ
とのこと。
ここで、クライアントと同じIPアドレスを持つマシンが
あって、そこからRSTが送られていればそういう症状が
起こるかなと思ったのですが...
あとは、クライアント-サーバ間のスイッチ等、ネットワーク
機器の不良とか。
kuri2
会議室デビュー日: 2005/01/28
投稿数: 10
投稿日時: 2005-02-07 11:30
いつも有難うございます。
接続は1対1です。
一度に受け付ける接続はひとつです。
今は、select待ちにはしていません。
ただaccept()して待っている待っているだけです。
I/Oは多重化していません。
接続が終了すると、コマンドのsend()、recv()してから
close()します。その後accept()をして待っています。
bind()->listen()->accept()->recv()->send()->close()->accept()、、
の繰り返しです。
少し気になることがあるのですが、ソケット番号がなくなるとどうなるのでしょうか?
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2005-02-07 22:15
ふむふむ。

コード:

bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
listen(listenfd, LISTENQ);
for( ; ; ){
connfd = accept(listenfd, (SA *)&cliaddr, &clilen);
recv(connfd, readline, m, rflags);
send(connfd, sendline, n, sflags);
close(connfd);
}



こんな流れでしょうか。
(カーネルがクライアントに返事をした)保留状態の接続があるのに、
accept()がブロックする理由は無いですね。
# この流れだと、accept する前に切断されていたら accept がエラーを
# 返すか、何事もなかったようにみえるかどちらかになるはずですし。
クライアントが connect() 出来てしまってるのが「何かの間違い」
のような...
サーバのプログラムは悪くなさそうですね。

原因を追求するには、スニファーでも仕掛けないと出来なさそうな
気がします。

引用:

kuri2さんの書き込み (2005-02-07 11:30) より:
少し気になることがあるのですが、ソケット番号がなくなるとどうなるのでしょうか?


「番号がなくなる」とは? リソース制限の上限いっぱいまで使い切った
場合、ということでしょうか?
それなら、accept() はエラーを返すと思うですが... やったことは
ないです。
# EMFILE もしくは ENFILE
クライアント側からは、「ただ接続開始要求のパケットが
届かなかっただけ」のように見えるはずです。
# そういう場合、サーバ側のOSは何もせずに無視するきまりです。

[ メッセージ編集済み 編集者: ぽんす 編集日時 2005-02-07 22:24 ]

スキルアップ/キャリアアップ(JOB@IT)