ネットワークプログラミング相談室 Port24
レス数が1000を超えています。これ以上書き込みはできません。
0001lmtp
2009/07/07(火) 00:46:28Programming UNIX Socket FAQ (日本語訳)
http://www.kt.rim.or.jp/~ksk/sock-faq/indexj.html
Winsock Programmer's FAQ (日本語訳)
http://www.kt.rim.or.jp/~ksk/wskfaq-ja/
関連リンクは>>2-10辺り
足りなかったら適当に付け足してね
前スレ
ネットワークプログラミング相談室 Port23
http://pc12.2ch.net/test/read.cgi/tech/1230466044/
関連スレ
ネットワークプログラミング雑談
http://pc12.2ch.net/test/read.cgi/tech/1235800707/
Java ネットワークプログラミング 【教えて!】
http://pc11.2ch.net/test/read.cgi/tech/1086238859/
0951938
2009/10/10(土) 10:01:02RecvAcceptorState state = STATE_WAIT_TYPE; // 初期状態はType待ち
void recv_acceptor() // recvイベント発生に呼ばれるコールバック関数
{
while (buf.size() > 0) {
byte = buf.pop(1)
switch (state) {
case STATE_WAIT_TYPE: // Type待ち状態
tlv.type = byte; // Type値が決定
state = STATE_WAIT_LEGTH; // 次の状態(Length待ち)へ遷移
break;
case STATE_WAIT_LENGTH: // Length待ち状態
tlv.length = byte; // Length値が決定(Lengthフィールドが1byte固定である事を仮定)
value_counter = tlv.length; // 受信カウンタをLength値で初期化
state = STATE_PROCESS_VALUE; // 次の状態(Value処理中)へ遷移
break;
case STATE_PROCESS_VALUE: // Value処理中状態
:
if (メッセージ組立て完了) {
: // 受信メッセージ処理のアクションを起動する
: // もし階層的なTLV構造であれば、>>947のメッセージ解析処理を呼ぶ
state = STATE_WAIT_TYPE; // 初期状態へ遷移(必要であれば他の再初期化処理も)
}
:
break;
}
}
}
(更に続く)
0952938
2009/10/10(土) 10:01:59>>931の場合、Lengthとして4byte固定を想定しているみたいだから、
上記の疑似コードに対して、Length待ち状態をSTATE_WAIT_LENGTH1..._LENGTH4に分割するか、
あるいはLength受信カウンタを追加する、といった改造を加える必要があるから、注意してね。
他にも、pop値は1byte固定になってるけど、Value処理中状態ではNbyteに高速化すべきだろうし。
0953デフォルトの名無しさん
2009/10/10(土) 12:50:43yacc 使えばいいんじゃね?
作らなきゃいけないのは、レキシカルアナライザ部分だ。
0954デフォルトの名無しさん
2009/10/10(土) 13:14:500955デフォルトの名無しさん
2009/10/10(土) 14:25:34一度書いたらいろんなプロジェクトで使いまわしできるもんだし。
0956デフォルトの名無しさん
2009/10/10(土) 14:29:250957デフォルトの名無しさん
2009/10/10(土) 16:27:51イベント駆動TLVデコーダの話なんじゃないの?
0958938
2009/10/10(土) 23:16:02# スレの流れが錯綜しそうなので、強引にマトメてみる。
最も外側のTLV構造のデコード処理は(>>950-952に書いた)イベント駆動方式(PUSH型)で実現できる。
この部分は比較的に単純なステートマシンだから、わざわざyaccみたいなコードジェネレータを
持ち出す必要性は(個人的には)感じられない(>>957)。
検討課題になるのは、メッセージを組立てた後に、階層的なTLV構造の内側をデコードする
(>>938の)プロセス駆動(PULL型)処理だと思う。
TLV方式は拡張性があるから、必要に応じていくらでも要素を追加できる。
しかも、それに対応するコードは(>>938で書いたような)単純なイテレータで実現できるから、
コピペでコーディングできる。>>955の言葉を借りれば、プロジェクト間で使いまわしができる。
とはいっても単調なコーディング作業の連続だから、(>>948の言う)関数ポインタを活用したり、
あるいはテーブル駆動なコーディング様式を検討したくなるのは、自然な発想だと思う。
そして、それを追求するとTLVデコード処理に特化した俺様言語(DSL)が欲しくなるのも自然な成り行き。
で、DSL(Domain Specific Language)を定義して、その言語処理系(コードジェネレータ)を
開発してみては?という提案が、>>933になる。それに対して、新たにメタ言語を定義して
処理系を開発するのは面倒だから、既に存在しているyaccで(メタ言語を)代用できるんじゃね?
ってのが、>>953の提案。ここでのTLVデコード処理はプロセス駆動方式(PULL型)だから
yaccとの相性は良いかもしれない(>>954)。容易に実現可能である、とまで断定はできないけどね。
(続く)
0959938
2009/10/10(土) 23:20:31最後に、>>956の意図をエスパーしてみたら、通信プロトコル(の状態遷移)そのものをDSLあるいは
yaccで記述できないのか?に読めた。もしそうなら、UNIX板の「yacc & lex」スレ内にある
レス#112-120で議論されていたから、まずそちらを参照してみて。
# 最後に訂正。>>958内にあるアンカ>>938は誤り。>>947が正しい。
0960デフォルトの名無しさん
2009/10/11(日) 00:45:27イベント駆動だから、yaccで直接書こうとすると、
yyparseをコルーチン化する必要があるぞ。
しかも不完全パケットを受けた状態を
それぞれ非終端記号にする必要がある。
ある程度はまとめられるとしてもね。
>>931のF()は一旦意味のある単位にまとめるのに集中して、
その結果をparseする別のコルーチンに渡すやり方なら簡単だけど。
0961デフォルトの名無しさん
2009/10/11(日) 08:29:230962デフォルトの名無しさん
2009/10/11(日) 10:12:13解釈勝手すぎくね?全部主観じゃね?うざくね?
0963931
2009/10/11(日) 10:20:40push/pullの概念がわかりません
>>960
コルーチンの方が楽っすかね?
とりあえず、>>951みたいな形で
stateとcounterを持たせる方法で書き始めました
>>962
何もしなくて、批判文句垂れる奴がうざいとおもますぅ><
0964デフォルトの名無しさん
2009/10/11(日) 11:44:08使うフレームワークが固定でそういうわけにもいかないんでしょう
0965938
2009/10/11(日) 11:45:06yaccとイベント駆動の組み合わせで生まれる問題(push/pull不整合)については、
>>961が1行レスでマトメてくれたので、これ以上はツッこまない。ただ、2点だけ補足。
・イベント駆動問題の解決方法はコルーチンだけではない。UNIX板で紹介したWebアプリの場合、
(コルーチンを使わずに)別の方法を使ってI/Oライブラリ(yylex()関数)内で吸収させている。
・イベント駆動問題はI/Oライブラリで吸収できる程度の問題だけど、他にも(ライブラリでは
吸収できない)本質的な問題(制約)が存在する。具体的な内容は省略。
>>963
push/pullやコルーチンなどの話題は、yaccとイベント駆動を組み合わせた場合に限定できるから、
元の質問(>>931)に関しては無視して進めればいいと思うよ。(これも個人的な主観かもしれんが)
0966デフォルトの名無しさん
2009/10/11(日) 11:50:38フレームワーク(他にもデザインパターンなど)という言葉の幻想(固定観念)に囚われることなかれ
0967デフォルトの名無しさん
2009/10/11(日) 12:09:34> // フレームワーク側で、recvイベントが発生した際に呼ばれる関数。
このフレームワークを変更可能であると想定していいのかね。
0968931
2009/10/11(日) 12:34:35一応このフレームワークを使おうって流れ(チームで)なんで変更できなさそうです。
フレームワーク側は、
bonblockingソケットを使っていて、EAGAINを帰すまで読み込んだ後、コールバック呼ぶっぽいです
0969デフォルトの名無しさん
2009/10/11(日) 19:50:570970デフォルトの名無しさん
2009/10/11(日) 19:52:000971デフォルトの名無しさん
2009/10/11(日) 19:54:130972デフォルトの名無しさん
2009/10/11(日) 21:53:200973デフォルトの名無しさん
2009/10/11(日) 22:58:400974デフォルトの名無しさん
2009/10/11(日) 23:04:430975デフォルトの名無しさん
2009/10/12(月) 11:51:39ジュールもブロックされそうだな
0976デフォルトの名無しさん
2009/10/12(月) 12:01:450977デフォルトの名無しさん
2009/10/12(月) 12:23:450978デフォルトの名無しさん
2009/10/12(月) 14:14:55そろそろ産め。
0979デフォルトの名無しさん
2009/10/12(月) 15:20:590980デフォルトの名無しさん
2009/10/12(月) 17:50:53ゲームつくるときに、たとえば12345番のポートでお互いUDPで
送受信するとします。
きっとそれはうまくいくんでしょうけど、そもそもだれか別アプリが
わざとこの12345にゴミパケット投げたりしたらどうなるんでしょう。
ゲーム側でいろいろチェックしとかないといけないってことで
いいんでしょうか。
0981デフォルトの名無しさん
2009/10/12(月) 18:09:00基本的にはそのとおり。
0982デフォルトの名無しさん
2009/10/12(月) 18:10:53そういうこと
Webプログラミングと似たような感じで、基本は送られて来たデータを信用しない
0983デフォルトの名無しさん
2009/10/12(月) 18:36:29>>982
どもです。
遅いのを気にしないならTCPにしとけばよいんでしょうか。
仮に10人でできるゲームだとして、他の全部のマシンとコネクション
はるってのは、なにも送受信してなければメモリもCPUも大した負荷
じゃないんでしょうか。
でも座標いっぱい送りあうなら、あんまりTCP向いてないんですよね?
多人数なアクション作るんだったら、基本TCPはホストになった
マシンとだけはっておいて、あとはUDP1こあけておき、
座標とかどうでもいいものはUDPで、ホスト経由せず全員になげて、
重要なものはTCPでホスト経由でほかのクライアントに通知、とか
でしょうか。
0984デフォルトの名無しさん
2009/10/12(月) 18:41:56悪意のあるクライアントが不正なデータを送りつけてサーバをダウンさせたり乗っ取ろうとするかもしれないし
0985デフォルトの名無しさん
2009/10/12(月) 19:00:03数十ならTCPでも余裕。
ただ、クライアント/サーバ構成にした方がいいと思うけど。
クライアントはサーバとだけ通信すればいいんで。
0986デフォルトの名無しさん
2009/10/12(月) 20:17:01チェックていっても、まあマジックナンバーつけるとかチェックサムとか
値のレンジチェックくらいしか思いつかないがおk?
>>985
そういうもんなんですね。
なんか気を使ってサーバーに負担をかけないようにとか考えて
ちょくせつクライアント同士でとかおもったけど、
そこまで気にしなくていいってことでしょうか。
0987デフォルトの名無しさん
2009/10/12(月) 21:05:19マジックナンバーつけて暗号化して、
複合化してマジックナンバーチェックすれば
中間者攻撃でも無い限り大丈夫と思われ。
0988デフォルトの名無しさん
2009/10/12(月) 23:58:12ダミーデーター送りつけたりするひとはいるね
だからマジックナンバーとかチェックサムとか値のレンジチェックは必要
0989デフォルトの名無しさん
2009/10/13(火) 08:46:28recvfromすればいい。
0990デフォルトの名無しさん
2009/10/13(火) 08:52:29制御しなかったらの話だけど
再送やソートの有無や優先度をパケット単位で指定出来る疑似TCPを
UDPで実装しようと前から思ってるんだが難しい・・・
そういうフリーのライブラリ無いのかねぇ
DirectPlayはそんな感じだったが、今じゃサポート外だしバグもあるらしいし・・・
0991デフォルトの名無しさん
2009/10/13(火) 09:06:00それならTCP使えばいいじゃんって思うけど、なぜUDPにこだわる?
0992デフォルトの名無しさん
2009/10/13(火) 09:22:17>>980
connectすればいいんじゃね?
0993デフォルトの名無しさん
2009/10/13(火) 09:43:510994デフォルトの名無しさん
2009/10/13(火) 10:31:46そりは再送が必要ないデータと必要なデータとで、UDPとTCPを使い分けるか組み合わせればいいんでそ。
NBT(NetBIOS over TCP/IP)だと、アドレス解決にはUDPが、データ転送にはTCPが使用されているし、
逆に、RTSPみたいなストリーミングでは、データ転送にはUDPが、その制御にはTCPが使用されている。
それを、わざわざUDPだけで苦労して実装する価値があるのかが疑問なんだが。
0995デフォルトの名無しさん
2009/10/14(水) 00:36:58・TCPの再送が邪魔になる
これらのケース以外は迷わずTCP使ってるな。
0996デフォルトの名無しさん
2009/10/14(水) 02:48:10それらの中間の特性を持つプロトコルを
UDP上に実装したくなるというのは分からないでもない。
たとえば、粒度の小さいトランザクションが大量に発生する
大規模分散アプリケーションでは、転送の信頼性が要求される一方で、
コネクションのオーバヘッド(時間/リソース)が無視できなくなる。
0997デフォルトの名無しさん
2009/10/14(水) 03:32:170998デフォルトの名無しさん
2009/10/14(水) 03:33:150999デフォルトの名無しさん
2009/10/14(水) 03:34:391000デフォルトの名無しさん
2009/10/14(水) 03:46:48http://pc12.2ch.net/test/read.cgi/tech/1255459388/
10011001
Over 1000Threadもう書けないので、新しいスレッドを立ててくださいです。。。
レス数が1000を超えています。これ以上書き込みはできません。