
現在C言語にソケット通信を作成しているのですが、read関数内の作成でつまずいています。
ご存知でしたら教えてください。
自分なりに調べた結果read関数の戻り値は受信した
バイト数、毎回指定サイズ受け取るとは限らないと
いうことでした。
そこでread関数を無限ループで回し
指定サイズ受信したら、ループを抜ける使用にしたのですが、受信バイトが0だった場合はどうすればよいのでしょか?
よくサンプルなどでは、0だったらエラーと判断し、すかさずbreakしているのですが、一度でも0バイトを受信すると、それ以降は1バイト以上受信出来ないものなのでしょうか?
もし出来ないのなら一度でも0を受信したら、breakしようと思っています。
出来るのでしたら、タイマー設定をし、指定受信バイトに満たなくても一定時間が過ぎたらループから抜ける使用にしたいと考えています。
そのほか良い方法があれば教えてください。
分かりずらい説明になってしまいましたが、宜しくお願い致します。
No.5ベストアンサー
- 回答日時:
selectの戻り値が1となったのならば一歩前進です。
あとは、FD_ISSET()して期待通りのソケット番号にデータきていれば受信できると思います。
ところで今回のソースでFD_SET()のところはどうなっていますか?
selectでいつも0となるのはFD_SETがちゃんとできていないような気がします。
前回と今回のソースで差分をチェックしてみてはどうでしょうか。
がんばってください!
あと、ほかに参考になりそうなページをのせてみます。
「selectを使う」の項目が役立ちそうです。fdという変数にaccept()した戻り値を入れるようにすればいけます。
参考URL:http://www.ops.dti.ne.jp/~allergy/socket/socket. …
またまた中間報告です。
http://yonex1.cis.ibaraki.ac.jp/progai4/public_h …にあるサンプル(チャットプログラム)でタイムアウトを10秒に設定し、クライアントからのデータ送信を10秒以内、10秒以外で確認した結果、以内の戻り値は1、以外の戻り値は0になりました。これがemonkyさんのおっしゃっていたタイムアウト設定だと思います。
No.7
- 回答日時:
No6です。
別方法ですが、ソケットオプションを指定する方法もあります。
//ディスクリプタにタイムアウト設定
setsockopt(socketfd,SOL_SOCKET,
SO_RCVTIMEO,&tv,sizeof(tv));
if(read()<0){
if(errno==EWOULDBLOCK){timeout}
}
お礼遅れまして申し訳御座いません。
上記の方法はまだ、試していないのですが、
ずっとselectの戻り値が0だった理由が分かりました。
select関数を使用する際、if((qq=select(fd,NULL,NULL,NULL,&time)) == xxx){ みたいにifの
判定をしていました。
そこで、ifをとったところ1が帰ってくるようになりまいした。
どうも有難う御座いました。
No.4
- 回答日時:
タイムアウトの設定をしない場合は、待ち時間が0となり、すぐにタイムアウトしてしまいselectの戻り値が0になると思います。
参考にされているソースだとaccept()できたらプロセスを作っていますが、とりあえず通信したいのであれば同じ関数内ですませてしまうというのもできると思います。
サーバソケットsocket生成
listen()
↓
accept()
↓
while(1)
{
select()
↓
recv()
}
としてみたらいかがでしょうか。
emonkyさん何度もお助け文有難う御座います。
一応こちらの中間状況をお知らせ致します。
上記でアドバイスを受けた通り、なるべくシンプルな
コードにしてみました。
しかし、結果は変わらず。。。
そこで同サイトにselect関数内でタイマーを使用したサンプルコードがあったのでそちらを動かしselectの戻り値を確認したところ1が帰ってきました。
試しにそのサンプルからタイマー設定の時間を0に
設定したり、select関数の第5引数をNULLにセットしたところ、それでも1が帰ってきてしまいました。
このような切り分け作業を行ったのですが、あと他に考えられることはありますでしょうか?
No.3
- 回答日時:
とことん行きましょう!!(^^;
selectの結果がいつも0というのは受信イベントがみつかってなくタイムアウトしています。
私の書いたソースでsockとありますが、この変数にはrecv()で使う引数と同じソケット番号が入っていなければいけません。
ちなみに、私はTCPで接続を行っているものと思い込んでいますがあっていますか??
TCPでやろうとしているのならば、FD_SET()する時点で相手と接続できていると思いますのでそのソケット番号を使ってください。
つまり、サーバ側であればaccept()したときの戻り値が受信で使うソケット番号となるのでFD_SET()もこの値を使う。クライアント側であればconnect()で使用したソケット番号となります。
返事が遅れ、申し訳ありません。
一応emonkyさんがおっしゃている通りの設定になっていると思います。
現在、僕が参考にしているサンプルです。
http://hp.vector.co.jp/authors/VA003991/kouza/se …
上記サンプルはselectでタイムアウトの設定はして
いないのですが、これにemonkyさんが教えてくれました、コードを追記しました。
補足ですが、タイムアウトの設定をしない状態でも
select関数の戻り値は0でしたが、これは正常なので
しょうか?
No.2
- 回答日時:
#1:emonkyです
selectの説明は参考URLでお願いします。
2番目の引数に設定するのはあっています。2番目の引数は受信のイベントについてチェックします。
5番目の引数にタイムアウト時間の設定をします。
selectでタイムアウトが発生すると戻り値が0となります。
簡単なソースの流れを書いておきます。
参考にして組んでみてください。
fd_set recvFDs;
struct timeval tv;
FD_SET(sock, &recvFDs);
tv.tv_sec= 5; /* 5sec */
tv.tv_usec=0;
ret = select(sock+1,&recvFDs,0,0,&tv);
switch(ret)
{
case -1:
/* error */
break;
case 0:
/* timeout */
break;
defualt:
if(FD_ISSET(sock,&recvFDs))
{
recv();
}
}
参考URL:http://www.linux.or.jp/JM/
例文まで記述して頂き有難う御座いました。
一応意味を理解し、上記の通りにプログラムを書いて
みたのですが、どうしてもselect関数の戻り値が0になってしまいます。試しに第5引数をNULLに戻しselect関数を実行させたのですが、これも変わらず戻り値は0で、正常終了していまいした。何が原因でしょうか?
No.1
- 回答日時:
readの戻り値が0だった場合は、接続相手とのコネクションが終了しています。
TCPのFINを受信したときに0になったような・・一定時間でチェックしたいということならばselectという関数を使用したらどうでしょうか?
ここではselectの使い方はいたしませんが、詳細を希望ならまた説明したいと思います。
迅速な回答ありがとうございました。
selectは使用しているのですが、サンプルを真似たのでしっかりとした使用方法が分かりませんのでご教授ください。
また、現在selict内の第3~5引数はNULLがセットされています。
以上、宜しくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Outlook(アウトルック) 標準アカウントをOUTLOOKアプリに登録するとほかのアカウントのメールもこのアドレスに受信される 1 2023/02/03 20:34
- ガラケー・PHS SMSメールの受信遅延原因はガラケー自体の欠陥では 8 2022/08/06 11:46
- 迷惑メール・スパム ソフトバンク関係の方にお伺います。いわゆる迷惑メールが一日あたり100件位送られきます。 迷惑メール 2 2023/05/24 19:54
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- その他(メールソフト・メールサービス) メールサーバーは「PC側がメールをDL済みか否か?」を何を以て感知するのか? 2 2022/12/20 14:56
- 高校受験 中3女子です。 通信制高校の受験を受けたのですが、遅刻した上に、言い訳になりますが、緊張で手が震えて 1 2023/01/29 10:19
- その他(パソコン・スマホ・電化製品) ウィルスバスターモバイルについて。 iphone12 miniで、ウィルスバスターモバイルを使ってい 2 2022/07/10 12:59
- ハローワーク・職業安定所 職業訓練校 バイト どちらを優先させるべきか 4 2023/04/23 19:00
- 新卒・第二新卒 新卒の最終面接後に健康診断を受けさせられる意味は? 4 2023/08/10 00:47
- ストレス 現在高3で通信制に通っている者です。 高1の時は全日制高校に通っていたのですが精神疾患を持ったことが 3 2022/04/26 00:50
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
ウインドウズメディアプレイヤ...
-
PDAのシリアルポートデータの消去
-
writeで止まります
-
visual c# 2010 シリアル通信ア...
-
winsockの動作について。
-
FormatMessageでのバッファサイ...
-
socket: recvはいつ,どれだけ...
-
シリアル通信の出力バッファと...
-
ソケット通信内 read関数について
-
シリアル通信エラー
-
winsockでソケット通信の開発を...
-
WinsockAPIのrecvfromの受信デ...
-
SerialPortのDataReceivedイベ...
-
Macターミナルで実行中のプログ...
-
メモリのセグメント違反の解決...
-
TCP/IP通信時のサーバーからの受信
-
バックグラウンドのプロセスの...
-
HTMLからJava
-
チェックボックスの周囲の色が
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
「スイッチングハブのバッファ...
-
winsockでソケット通信の開発を...
-
シリアル通信の出力バッファと...
-
WriteFile()でのデータ送信がで...
-
Linuxでのシリアル通信について...
-
WinsockAPIのrecvfromの受信デ...
-
socket: recvはいつ,どれだけ...
-
SerialPortのDataReceivedイベ...
-
ClearCommError呼び出し時のCE_...
-
TCPでの非同期型select関数につ...
-
シリアルポート通信
-
シリアル通信 大きいサイズの...
-
winsockの動作について。
-
ソケット通信内 read関数について
-
COMポートの同時オープン同時読...
-
SocketのSend関数でのCLOSEの検...
-
waveIn、waveOutでの音声録音・...
-
write関数でEAGAINのエラー発生...
-
rs232cでの受信データ(mscomm)...
おすすめ情報