ちくのう症(蓄膿症)は「菌」が原因!?

はじめまして。dekatyoと申します。
borland c++ 4.0にて開発をしております。
タイトルの通り、setsockoptにて指定した、タイムアウトの確認方法を探しています。
一通り探してみたのですが、何分私も、初めて担当した言語で戸惑っております。
恐れ入りますが、ご回答をお願い致します。

A 回答 (2件)

「タイムアウト発生をどうやって検知するか」という質問だと捉えましたがよろしいでしょうか?



BolandC++が、BSDソケットの仕様に準拠しているとしての話ですが・・・

タイムアウトを気にするということはブロッキングI/Oモードです。
send/recvは、正常にデータ送信/データ受信ができない限り、setsocketoptで設定したタイム
アウト値まで、リターンしません。
そして、タイムアウトした時はエラーとして-1を返却します。
その時のグローバル変数errnoに、EAGAINまたはEWOULDBLOCK(sendのみ)が設定
されます。これがタイムアウトした事を示します。
(もしかすると、Winsockの仕様を取り込んでいるとGetLastErrorとかでエラー値を取得
 する形かも知れません。)
    • good
    • 0
この回答へのお礼

とても参考になりました。
ありがとうございました。

お礼日時:2006/11/02 18:12

送受信のタイムアウトの話ですよね。



受信側でrecv()を呼び出し、送信側で何も送信しなければ良いのではないでしょうか?
    • good
    • 0
この回答へのお礼

ご返答ありがとうございます。
参考にし、調査してみたいと思います。

お礼日時:2006/11/02 18:13

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

QWinsockで接続待ちタイムアウトを設定する方法

現在、WinsockAPIを使ってソケット通信プログラムを作っています。
 このプログラムの仕様の中で、接続待ちタイムアウトというものがあります。これはつまり、connect関数を実行してから応答が返ってくる(関数が値を返す)までの時間監視のことなのですが、そのような値をソケットに対して設定する手段というのはあるのでしょうか?

Aベストアンサー

あるとすれば、
setsockopt()
で設定できるソケットオプションのどれかということになります。
明確に書かれているものはありませんが、もしかすると、送信タイムアウトの設定で効いてくるかも知れません。

なければ、
(1)ソケットをノンブロッキングにして、
(2)connect()の完了を、タイマを掛けることのできるselect()で待ち、
(3)自分のタイムアウトが先にやってきたら、ソケットを捨てて、タイムアウト処理をする。
connect()の結果がタイムアウトで完了してもなお自分のタイマに残りがあれば、残り時間分のタイマを掛けて(2)に戻る。
というような実装になるように思います。

回答になっておりませんが、参考まで。

Qネットワーク切断を検出するには?

Linux上で動作するTCP/IP通信アプリケーションが、LANケーブル抜けによるネットワーク切断を検知するにはどうしたらよいのでしょうか?

外部からコネクションを確立した後にケーブルが抜けたとき、Linux側でソケットをcloseしたいのです。今はこれができておらず、接続状態のまま(netstatでみるとESTABLISHED)になっています。複数の接続を許していないので、ケーブルを繋いだあとにTCP/IPで再接続できません。

試したこと
ソケットに対するioctl(2)でifreq.ifr_flagsのIFF_UPフラグをみたけど検知不可
切断時にselect(2)がエラーリターンするかと思ったがだめ

ケーブルが抜けたとき、カーネルが eth0: link down とログに出力するのでどこか(/proc , /sys以下)を参照すればよさそうな気がするんですが…

Aベストアンサー

HP-UXなので微妙に異なる可能性はありますが、こんな感じです。
http://docs.hp.com/ja/B2355-60129/TCP.7P.html

QSocketのSend関数でのCLOSEの検知 [Linux]

Linux環境でSocket(dm:PF_INET,type:SOCK_STREAM)を使用しての、
Client&ServerプログラムをCで作成しているのですが、
そこでのSend関数の使い方についてご助力ください。

Client&Serverプログラムは下記のような動きをします。

[Client]
ServerへConnectした後、複数のDataを数秒間隔でServerへ
送信(send関数使用)します。受信(recvやread関数等)は、
一切行いません。

[Server]
ClientからのConnectを受け付けた後、Clientから受信(recv関数
使用)したDataを標準出力へ表示する。送信(sendやwrite関数
等)は、一切行いません。


さて、ここでもしClientプログラムがCloseを発行したり、マシン
DOWN等の理由でConnectionが切断され、Server側のSocketが
CLOSE_WAIT状態になった場合、Bufferに溜まっていたDataを
すべて受けきった後、recv関数が0を返してくれるので
相手が終了したことがわかります。

ここからが質問のMainです。

では、もしServerプログラムがCloseを発行したり、マシン
DOWN等の理由でConnectionが切断され、Client側のSocketが
CLOSE_WAIT状態になっても、CLOSE_WAIT直後のsend関数が
なぜか正常に処理されてしまいます。無論このDataは、
Server側は受け取りません。この次のsend関数実行時に
EPIPEが返ってくるので、ここでようやくSocketが切断された
ことが判ります。

これを何とかCLOSE_WAIT状態になった直後から、send関数で
切断を検知できるようにできないでしょうか。

よろしくお願いします。

以上

Linux環境でSocket(dm:PF_INET,type:SOCK_STREAM)を使用しての、
Client&ServerプログラムをCで作成しているのですが、
そこでのSend関数の使い方についてご助力ください。

Client&Serverプログラムは下記のような動きをします。

[Client]
ServerへConnectした後、複数のDataを数秒間隔でServerへ
送信(send関数使用)します。受信(recvやread関数等)は、
一切行いません。

[Server]
ClientからのConnectを受け付けた後、Clientから受信(recv関数
使用)したDataを標準出力へ表示する。送信(se...続きを読む

Aベストアンサー

#3です。
>完全な保証ではないのですが、”送れた/送れない”をきちんと
ログとして残す必要があるのです。

なるほど、そういう事情でしたか。それだと、それなりの信憑性が要求されますね。

>それと最初にご提案いただいたrecvをNonBlockモードで呼び出す
方法ですが、これだとrecvのリターン値は0が返ってこないでしょうか?

Linuxで以下のような、プログラムを組んで確認しました。

//送信前に、ノンブロッキングでrecvする。
ret = recv(sock,rbuf,sizeof(rbuf),MSG_DONTWAIT);
if (ret == -1 && errno == EAGAIN){
//正常なので送信可能
ret = send(sock,msg[i],sendlen,0);
if (ret != sendlen){
//送信エラーの処理
}
}else{
//切断検知時の処理
 // CLOSE_WAITになると ret=0が返る
}

サーバー側で切断時、直ちにrecvで戻り値=0となり、エラーの検知ができました。ret==-1 かつ errno==EAGAIN
であれば、回線は正常状態です。

#3です。
>完全な保証ではないのですが、”送れた/送れない”をきちんと
ログとして残す必要があるのです。

なるほど、そういう事情でしたか。それだと、それなりの信憑性が要求されますね。

>それと最初にご提案いただいたrecvをNonBlockモードで呼び出す
方法ですが、これだとrecvのリターン値は0が返ってこないでしょうか?

Linuxで以下のような、プログラムを組んで確認しました。

//送信前に、ノンブロッキングでrecvする。
ret = recv(sock,rbuf,sizeof(rbuf),MSG_DONTWAIT);
if (ret == -...続きを読む

QTCP/IP通信でのコネクションロスト(ソケットエラー)の検知について

インターネット上での対戦ゲームの作成を行なっているところです。
サーバーを挟んでクライアント間で双方向の通信を行なっています。

 A → サーバー → B
 A ← サーバー ← B

TCP/IPは信頼性の高い通信方法ということで、データ抜けなどは
心配しなくても良いと聞いています。
もし、データ抜けなどが発生した場合はコネクションロストの状態になると。

実際のプログラミングではソケットを使用しています。
コネクションロストが起きると、ソケットエラーかソケットクローズで検知できます。


実際に例えばクライアントAを強制終了させるとサーバーはただちに
ソケットクローズを検知します。


ここで、問題はデータを送っても届かないのに、
ソケットエラーもソケットクローズも起きない状態が発生することです。
これはインターネットの経路上になにか問題が発生したと考えていますが
このような状態はタイムアウトなどで監視する以外に検知する方法はないのでしょうか?


クライアントはウィンドウズでVB6.0のwinsockを、
サーバーはLinuxを使用しています。

なにかアドバイスをいただければありがたいです。

インターネット上での対戦ゲームの作成を行なっているところです。
サーバーを挟んでクライアント間で双方向の通信を行なっています。

 A → サーバー → B
 A ← サーバー ← B

TCP/IPは信頼性の高い通信方法ということで、データ抜けなどは
心配しなくても良いと聞いています。
もし、データ抜けなどが発生した場合はコネクションロストの状態になると。

実際のプログラミングではソケットを使用しています。
コネクションロストが起きると、ソケットエラーかソケットクローズで...続きを読む

Aベストアンサー

>>これはインターネットの経路上になにか問題が発生したと考えていますが
>>このような状態はタイムアウトなどで監視する以外に検知する方法はないのでしょうか?

多くのアプリは、タイムアウトで処理しているようです。例えば、経路途中のどこかのLANケーブルが抜けて通信が失敗した場合、すぐにエラーを検出して異常になるよりも、LANケーブルを差し込んだら、そのまま継続してくれるほうが嬉しいわけですからね。

もし、デフォルトのタイムアウトがいやなら、定期的に信号をやりとりする仕組みを組み込めばいいと思います。ただし、そのやりとり自体もタイムアウトになる可能性があるのと、連番を振って管理するなどしてエラー時の再送をやる場合、考慮無くやると、アホな結果を生む可能性もあるので、注意が必要です。このあたりの話題はソケット関係の情報を検索すると出てくると思います。

あまり厳密にやると複雑化する気もするので、シンプルにタイムアウトでの対処がいいかなと思います。

Qsocket: recvはいつ,どれだけ受け取るのか?

 現在,参考書にしたがってC++でソケットプログラミングを書いています.

 sendとrecvを非同期にするために,本では select関数やWSAAsyncSelect関数などを利用していて,実際,本のとおりに書いて上手く動いています.

 ここで伺いたいのですが,recvは,どうやって「データが届いたか」を知るのでしょうか.

 同期ならば,トランシーバでの会話のように送信側が「どうぞ」といって送受信を交代させることができますが,非同期ならばそれができません.

 NICとかが,プログラムに「届いたぞ!( or これから届くぞ!)」と教えてくれるのでしょうか.あるいは逆に,プログラムがNICに「届いてる?」と聞いているのでしょうか.仮に,ここに書いたような方法で届いたことが分かったとしても,どれくらい受け取ればいいかは分かりません(それも併せて教えてもらっているのでしょうか.データを送るときには,どれだけ送ればいいか分かりますよね.受信するときはどうしてるのかを知りたいと思っています).

Aベストアンサー

Linux しか知らないので Linux で説明をします。

NIC が通信パケットを受け取ると割り込みが発生し、CPU は割り込みを受け付けて、対応するデバイスドライバを起動します。この時、ドライバはソケットバッファと呼ばれる構造体にパケットの中身をコピーして、Linux カーネルの本体に渡し、そこで TCP 等の上位プロトコル処理が行われます。

一方、ユーザプログラムの方は、 select() なり read() で待っている訳ですが、OS はもちろんプロセスが何を待っているかを知っているので、対応する待ちの条件が満たされると、この場合は select() や read() が、抜けてくる(return する)訳です。

という事で、ユーザのプログラムは select() なり read() なりで受信データを「待つ」ことが必要です。もちろん select() や read() が呼ばれた時点で既に受信しているのならば、それらは直ぐに帰ってきます。read() や recv() はデータが届いた事を知る、というよりは、届いているかチェックして、まだ届いていなければ届くまで待つ(read() が抜けてこない)という処理になります。また NIC とユーザプログラムが直接やり取りをするのではなく、間にバッファがあって、対応するソケットのデータがある(受信済み)/ないか(未受信)、という問い合わせを行っているだけです。

ソケットの場合、データの送受信は非同期であり、送受信のタイミングのずれは(ソケット)バッファである程度吸収されます。もちろん、送受信バッファが満杯になった場合は流量制御が働いて、結果的に送信側の write() や send() が待ちに入ることになります。

Linux (Unix) のソケットの受信では、read() 等で指定されたバッファが常に満杯で返されるとは限らない設計になっています。つまり、その時に受信しているデータを返すだけなので、read() で返されたバイト数を必ず見ないと間違った動きになるので注意してください。

Linux しか知らないので Linux で説明をします。

NIC が通信パケットを受け取ると割り込みが発生し、CPU は割り込みを受け付けて、対応するデバイスドライバを起動します。この時、ドライバはソケットバッファと呼ばれる構造体にパケットの中身をコピーして、Linux カーネルの本体に渡し、そこで TCP 等の上位プロトコル処理が行われます。

一方、ユーザプログラムの方は、 select() なり read() で待っている訳ですが、OS はもちろんプロセスが何を待っているかを知っているので、対応する待ちの条件が満...続きを読む


人気Q&Aランキング