08/06/14 09:34:50
しかしなんだね、g++ってVC8とは若干違うよね
accept()関数の第三引数の
accept(fd1, (struct sockaddr *)&caddr, &len))
lenだが、VC8ならintでも無問題なのだけど、g++はsize_tじゃないと嫌だと
怒ったりとかと少し戸惑う、>>330でした
332:デフォルトの名無しさん
08/06/14 09:54:59
POSIXではsocklen_tだけど、intで実害はない。
size_tとしてしまうのは誤り。
socklen_tとint(やsize_t)が同じサイズか判定をどこかに入れておくと安全。
// 偽なら負の添え字になりコンパイルエラー
#define STATIC_ASSERT(cond) extern int static_assert_array[ (cond) ? 1 : -1 ];
STATIC_ASSERT(sizeof(int) == sizeof(socklen_t))
333:デフォルトの名無しさん
08/06/14 10:05:46
>>332
Thx
物知りですね、勉強になります
gccの場合、accept()関数の第三引数は、int型でコンパイルに成功してたんだけど、g++でコンパイルした際にエラーが出たんで
なんでかなと思ってた、コンパイラに依存しないようにアサーションマクロを書いておくと、メモメモ
334:デフォルトの名無しさん
08/06/14 14:25:52
Winsockで非ブロッキングモードにしたいときは
selectでウインドウハンドルとそのウインドウのプロシージャを設定するけど
最初はウインドウAでメッセージ受けてたけど
次はウインドウBでメッセージ受けるように変更
とかいうことはできますか?
本当はウインドウハンドル指定しなくてよければ通信メッセージ受けるところだけ独立させたいんだけど
335:デフォルトの名無しさん
08/06/14 14:32:58
>>334
WSAEventSelectを使えばウインドウハンドルはいらない。
336:デフォルトの名無しさん
08/06/14 14:35:32
>>335
お~ ウインドウハンドルいらない版もありましたか
ありがとうございまつ
337:デフォルトの名無しさん
08/06/14 16:12:06
winsockについてです
gethostbynameではwinsockが確保したメモリが返されてきますが
これはどうすると解放できるのでしょうか?
338:デフォルトの名無しさん
08/06/14 16:17:39
>>337
gethostbynameでググルと一番上に解説が出てくるし
339:デフォルトの名無しさん
08/06/14 20:59:48
>>329なんだけどさ
>>327
が書いてたんで、rubyのソケットのライブラリを見てたら、やっぱ個別に
sockの関数と1対1に対応するメソッドを持ってるよね
>>326は
1対1に対応するメソッドを作ると、恩恵は受けにくいと言うし
ネットワークプログラミングとは直接関係ないけど、どっちがいいんだろうな?
この問題にはいつも悩まされる
永遠の命題なのか・・・・orz
340:デフォルトの名無しさん
08/06/14 21:10:21
>>339
たとえば、自分向けのライブラリを作るなら、いきなりconnectで繋がって、closeで閉じるライブラリを作り置きしておくと、今後ずっと楽になる。
341:デフォルトの名無しさん
08/06/14 21:19:02
>>340
わかりやすい説明、ありがとう
たしかに、それは言えるのだけど、ついつい、かまえてって言うか、型にはめようとして
再利用性だとか、拡張性だとか、考えてしまいクラスの設計には、いつも苦労するんだよね、俺の場合
もう少し気楽に考えた方がいいかもね
342:デフォルトの名無しさん
08/06/14 21:26:20
>>341
共通の機能は基本クラスに、専用の機能は派生クラスに分散。一つのクラスで機能を欲張らないのが設計のコツ。
343:デフォルトの名無しさん
08/06/14 21:27:55
>>341
C/C++で書いてるんなら、いつでも下に降りられるから、ある意味
どうでもいい気がする。
rubyみたいな奴だと、標準で抽象度の高いAPIしか用意されてないと
そこより下に降りたければCでextension書くしかないって話になる。
だからそういう設計になってるんだと思うよ。
344:デフォルトの名無しさん
08/06/14 21:34:17
>>341です
皆さん、いい話ありがとう
345:デフォルトの名無しさん
08/06/14 23:34:33
TCP/IPで、自ソケットが生きてる場合、一時的に通信経路に問題があってもsendは成功すると
思いますが、その後すぐにその問題が解決したら、相手側には届くのでしょうか?
346:デフォルトの名無しさん
08/06/14 23:36:06
>>345
いつか届く。
347:デフォルトの名無しさん
08/06/15 04:36:59
僕の想いも届いて!
348:デフォルトの名無しさん
08/06/15 06:09:21
winsockを使っていますが
”こんにちわ” ”こんばんわ”
を相手が送信したときに
2つのメッセージに対して
FD_READが2回発生するときと
1回しか発生しないときがあります
2回発生するときは
”こんにちわ” と ”こんばんわ” を別々に取得できて問題ないのですが
1回しか発生しないときは
”こんにちわこんばんわ”という1つの文字になってしまいます
送信相手が1回送信するごとにFD_READが1回発生するように設定することはできますか?
できないとして1送信ごとに何らかの記号をつけて識別したりするのでしょうか?
349:デフォルトの名無しさん
08/06/15 06:29:10
基本的にできない。「こんにちわ」と「こんばんわ」を別のものとして扱うなら、それぞれの頭に俺プロトコルのヘッダ(メッセージ長など)を付けて送り、受信側でそれを解釈する。
あと、どーでもいいけど「こんにちは」と「こんばんは」だと思う。
350:デフォルトの名無しさん
08/06/15 10:57:00
そういうときこそ、
SCTP。
おまいら使ってる?
351:デフォルトの名無しさん
08/06/15 14:04:34
>>348
そもそも
「こ」「ん」「に」「ち」「わ」と5回に分かれてFD_READが来ることだってありえるぞ。
TCPとはそういうもんだ。区別したけりゃストリームに自前で区切情報載せろ
352:デフォルトの名無しさん
08/06/15 15:09:49
>>349 351
ありなとうございまつ
Sendの末尾に区切り文字入れれば
1回で複数受信してもOKじゃね?
とか思ったけど1送信あたりでも分離することあるのですかorz
しかしそうなると
「こんに」「こんばんわ」「ちわ」という受信すらありえるような
それともTCPは受信順番も考慮するからそれはないと思っていいんでしょうか?
353:デフォルトの名無しさん
08/06/15 15:32:35
つ[延滞]
必ずしも送った順に相手に届くとは限らない
この辺はUDPとTCPの違いを調べれば分かる
354:デフォルトの名無しさん
08/06/15 15:58:37
>>352
TCPは順番は変わらないよ!。
355:デフォルトの名無しさん
08/06/16 11:35:18
マルチスレッドなプログラムでsocketを使った場合に、
thread1(){ send("ABCDE"); }
thread2(){ send("abcde"); }
の2つのスレッドが同時にsendをコールした場合、
相手側でrecvした時に、
"ABCDE"と、"abcde"が混ざることってありますか?
例えば、"AaBbCcDdEe"みたいに。
シングルスレッドな場合だと、
send単位で送ったデータはそのまま出て来ますよね。
356:デフォルトの名無しさん
08/06/16 11:50:15
せめて"ABabcdeCDE"くらいの例えならな
357:デフォルトの名無しさん
08/06/16 11:52:11
1. netstat -a で見れる情報(プロトコルやアドレス/ポート ステータス)は
どこから持って来てるんでしょうか?
(同じ情報を自分のプログラムから取得するにはどうすればいいでしょうか?)
2. TDImonか同等のプログラムのソースコードはどこかにないでしょうか?
358:デフォルトの名無しさん
08/06/16 11:53:48
netstatのソース見ればいいんでねぇの?
359:デフォルトの名無しさん
08/06/16 11:59:56
>>356
>"ABabcdeCDE"
これもありうる?
カーネルの中のソケット毎の送信バッファってのは、1つだよね。
複数のスレッドがsendをコールすると、その送信バッファに、
送信データが詰め込まれて行くんだと思うんだけど、
それがsend単位に区切られて詰められない可能性もあるってこと?
こういう動きって、OS依存?
send実行中に、スレッドがコンテキストスイッチしたらこうなるってこと?
2このスレッドが、同時に100Mバイトとかのデータをsendしたら、
そうなりそうな気がしないわけじゃないけど。
360:デフォルトの名無しさん
08/06/16 12:04:11
そもそも同期化もせずに 1 つのソケットに複数スレッドで書き込むな。
361:デフォルトの名無しさん
08/06/16 12:09:29
232Cでやっちまったことはあるな
362:デフォルトの名無しさん
08/06/16 12:50:47
>>360
確かにおっしゃる通りですね。
ってことは、やっぱりそうなる事もありうるってことですか。
363:デフォルトの名無しさん
08/06/16 19:19:51
>>362
実装依存だろうし、起きるかどうか考えるだけ無駄
364:デフォルトの名無しさん
08/06/16 21:45:50
ロックしろよ
365:デフォルトの名無しさん
08/06/16 21:51:18
Unixで同期モードならおきない気がする
366:デフォルトの名無しさん
08/06/16 22:11:13
>>365
どういった理由からですか?保障されているんですか?
367:デフォルトの名無しさん
08/06/16 23:13:06
TCPだったら、sendした順に届くとは限らない。
スレッド関係なしに。
だから、逐次処理で
send( "ABCDE" );
send( "abcde" );
とかやっても、相手側で
abcdeABCDEと受信することも普通にある。
368:デフォルトの名無しさん
08/06/16 23:19:20
おいおい。TCPでそれはないって。
369:デフォルトの名無しさん
08/06/16 23:22:45
>367
え??
370:デフォルトの名無しさん
08/06/16 23:30:04
次にお前は「ワーイ沢山釣れたー」と言う…
371:デフォルトの名無しさん
08/06/16 23:37:42
winsockならURLリンク(www.kt.rim.or.jp)
まぁ、どの実装でも、自前でコントロールすべしって結論になると思う
372:デフォルトの名無しさん
08/06/16 23:39:36
あれ?システムコール実行中にコンテキストスイッチて起るんだっけか?
373:デフォルトの名無しさん
08/06/16 23:47:19
起こらないとするなら、誰かがsendを喚ぶと、戻ってくるまで
システムフリーズするだけだな。
374:デフォルトの名無しさん
08/06/17 01:51:31
TCPは送信順番も送信内容も保障されるか破棄されるんじゃないの?
順番がかわるとか複製される可能性があるのはUDPじゃないの?
おれなんか間違ってること言ってる?
手元の参考書にそう書いてあるんだけど?
375:デフォルトの名無しさん
08/06/17 01:56:01
釣れた釣れた(^^)
バーカ >>374
376:デフォルトの名無しさん
08/06/17 02:01:15
>>375
スレ監視し続けてたんだね
お疲れ様
釣れて良かったね
おめでとう
377:デフォルトの名無しさん
08/06/17 02:46:29
>>372
普通に起こるだろ。
シグナルだって入るし、場合によっちゃスレッドだってスイッチする。
378:デフォルトの名無しさん
08/06/17 04:08:33
>>372
I/Oだったら普通にキューにぶっこんでコンテキストスイッチしないかな?
379:デフォルトの名無しさん
08/06/17 04:28:02
Winsockでconnect、send、recvそれぞれに個別のタイムアウト値を持たせたいのですが、
connectのみ
WSAWaitForMultipleEventsでタイムアウトを判断して
send、recvはsetsockoptを使って指定、
これで大丈夫でしょうか?
380:デフォルトの名無しさん
08/06/17 08:52:26
今の今までスレタイがtypoだと思ってた俺愕然。
381:デフォルトの名無しさん
08/06/17 09:58:45
65535まで続くよ!
382:355
08/06/17 10:05:16
>>367
シングルスレッドの場合でしょ、それは絶対にあり得ないと思うんだけど。
最近のカーネルは、カーネルプリエンプションだから、カーネル内部の処理
実行中にコンテキストスイッチすることもあるかも知れないけど、
ロジックの実行順序(逐次処理)が入れ替わることはないと思います。
>>373
それとはまた別の話ではないでしょうか。
sendを呼んだひとはブロックされるでしょうが、他のプロセスは
普通にシステムコールを実行することも、ユーザーランドのロジックも
実行できると思います。
>>374
私もそういう認識です。
TCPで1つのスレッドが送信した場合であれば、sendした順に相手側では
recv出来ると思ってます。(何回recvすれば良いかは判らんけど。)
途中でパケロスしたり、物理的に線が切れたりした場合は、受信側に届いた
部分まで(これも、相手がsendした順)が受信出来る。
なにか間違ってます? >> all
383:デフォルトの名無しさん
08/06/17 16:49:35
>>479
384:デフォルトの名無しさん
08/06/17 17:04:56
>>379
385:デフォルトの名無しさん
08/06/17 17:14:26
>>579
386:デフォルトの名無しさん
08/06/17 17:23:55
getaddrinfoはブロッキングを起こしますか?
387:デフォルトの名無しさん
08/06/17 17:54:23
AI_NUMERIC を付けない場合は起こします
388:デフォルトの名無しさん
08/06/17 18:07:41
LAN接続PC間で、低速、高ping回線の環境を再現するにはどのような方法があるでしょうか?
自作の俺プロトコルアプリが低速回線環境でどういった影響を受けるのか調べたいのですが。
環境はWindowsです(98orXP)
389:デフォルトの名無しさん
08/06/17 19:19:43
そういうソフト使えばいいだろ。
390:デフォルトの名無しさん
08/06/17 19:50:44
>>367
TCPでそれがあったら大変だろ
UDPでは十分ありうるだろうが
UDPは順序がかわるどころか
複製されたりもするらしいからな
しかしUDPって順序も保障されてないとなると
1パケットあたりの情報をどうやって認識するんだろうか
区切り文字やらパケットサイズ送っても
順序がかわったりしたらアウトだよな?
391:デフォルトの名無しさん
08/06/17 20:41:21
このスレに出入りする奴の発言とは思えんな。
392:デフォルトの名無しさん
08/06/17 21:56:19
UDPは来るか来ないかだけで、「パケット」という構造自体は保証されるだろ。
2つ以上のパケットをもってきて、その関連をどうこういうと面倒だけど。
393:デフォルトの名無しさん
08/06/18 09:28:59
UDPで順序が変わるってのはわかります。
例えば、
(1)udp_send("ABCD");
(2)udp_send("abcd");
とした場合、(1)で作成されたUDPパケットが相手HOSTに到達
するルートと、(2)で作成されたUDPパケットが相手HOSTに到達
するルートが同じだとは限らないですよね。
たまたま、(2)のUDPパケットが相手HOSTに到達するルートの方が
速い回線だったりした場合、受信側のHOSTでは、(2)(1)の順に
UDPパケットを受信する事もあり得ます。
UDPパケット毎の順序は不定ですが、複数のUDPパケットが混ざる
事はありません。(シングルスレッドの場合)
で、複製されるってのはどういう意味?
394:デフォルトの名無しさん
08/06/18 17:14:46
udp_send("ABCD");
とかが2回以上あったかのように
複数回届くことかと思われ
で、実際そういうことがある
パケットにインデックスとかつけて
2回目以降のやつは棄てればいいので問題ない
395:デフォルトの名無しさん
08/06/18 17:22:56
>>394
それって UDP側じゃなくて MAC側の仕様じゃないの?
結果は同じだけど・・・
細かすぎるか?w
396:デフォルトの名無しさん
08/06/18 17:48:55
UDPパケットがネットワーク上で消失するってのは判るんですが、
重複するってのはなぜ?
誰がパケットを複製するの?
マルチキャストであればルータがパケットを複製するってのは
判るんですが。
397:デフォルトの名無しさん
08/06/18 17:59:51
論理的にはあり得ないけど、ハードやOS側が腐っている場合は、
勝手に複製されてしまうこともあるって事ですか。
man ping より
重複パケットと障害パケット
ping ユーティリティは重複パケットと障害パケットを報告します。重複パケット
はユニキャストアドレスに対しては起こるはずのないものですが、リンク層での
不適切な再送信によって引き起こされるようです。重複は様々な状況で起こる可
能性があります。低いレベルの重複の存在は必ずしも警告にならないかもしれま
せんが、よい兆候ではありません。ブロードキャストもしくはマルチキャストア
ドレスに ping する時には、重複が起こることが期待されます。実際に重複する
のではなく、異ったホストから同じ要求に対して応答が行われからです。
障害を受けたパケットは明らかに重大な警告です。多くの場合、ping パケットの
経路のどこか (ネットワーク内かホスト内) のハードウェアの故障が考えられま
す。
398:デフォルトの名無しさん
08/06/18 18:03:13
よって、パケットの複製は、UDPだから発生するとかって話では
ないってことですね。
ただ、TCPだと、勝手に捨ててくれるけど、UDPだとそのまま
複数回受信しますということね。
と、なっとくしました。
考え方が間違ってたら、指摘してもらえると嬉しいです。