トップページ⇒tech
1001コメント320KB

ネットワークプログラミング相談室 Port27

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2010/12/25(土) 22:46:56
主にソケットに関しての質疑応答スレッドです。

Programming 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辺り
足りなかったら適当に付け足してね

前スレ
ネットワークプログラミング相談室 Port26
http://hibari.2ch.net/test/read.cgi/tech/1269343909/
関連スレ
ネットワークプログラミング雑談
http://hibari.2ch.net/test/read.cgi/tech/1235800707/
Java ネットワークプログラミング 【教えて!】
http://hibari.2ch.net/test/read.cgi/tech/1086238859/
0446デフォルトの名無しさん2011/07/09(土) 16:12:27.19
ごめんなさい、また間違えました
×それから、2230400のデータですが
○それから、230400のデータですが
スマソ
0447デフォルトの名無しさん2011/07/09(土) 16:29:52.14
UDPのデータにそういうふうに番号を付けて、
「何番までのデータは受け取った」とか「何番のデータはまだ来てない」とかそういう返事を受信側から送信側に送り返す
それを見ながら、未着の(たぶん失われたと思われる)データをもう一度送る
返事も失われることがあるので、何秒か返事がなかったら同じものをもう一度送る
「全部受け取った」という返事が来れば終了
0448デフォルトの名無しさん2011/07/09(土) 16:43:47.79
>>447
ありがとう
実装してみます
0449デフォルトの名無しさん2011/07/09(土) 17:02:16.53
TCPじゃだめなの?
0450デフォルトの名無しさん2011/07/09(土) 17:17:30.04
>>449
>>445です
マルチキャストの実験もしてみたいので、TCPではムリポなのでUDPに拘っています^^;
0451デフォルトの名無しさん2011/07/09(土) 17:55:46.30
マルチキャストで複数(多数)の受信者から違うパケットの再送要求が来たらどうするつもりなんだろう
0452デフォルトの名無しさん2011/07/09(土) 17:57:48.84
仮にどうにかできたとして
果たしてそれはマルチキャストと言えるのだろうか
0453デフォルトの名無しさん2011/07/09(土) 18:24:30.11
>>451>>452
>>448です
そうですね、やはりapache の実装のように、子プロセスのインスタンスを生成し
管理するような、システムを構築するべきでしょうね
0454デフォルトの名無しさん2011/07/10(日) 17:16:36.87
>>452
パソコンサンデー的なものになると思う。
マルチキャストでネトゲのパッチ配布実験とかしてなかったっけ。もちろん実験だけで実用にはならんけど。
0455デフォルトの名無しさん2011/07/10(日) 18:54:57.63
まずTCPのセッションを複数張って実装してみて、
それで駄目ならUDPとかマルチキャストとか考えるべき。
大抵TCPで何とかなる。動画サイトを見ろ。
0456デフォルトの名無しさん2011/07/10(日) 18:56:06.09
それから、>>439
確実に知りたければ"Path MTU Discovery"するしかない。
まあ途中に入っているルータが正直に応えるかどうか不明だが。
IPv6の場合はルータの対応が必須だけども。
0457デフォルトの名無しさん2011/07/10(日) 22:06:00.41
>>456
IPv6でも続々と変なルータやFireWallが増えてきてるので、
PMTUDが通る前提は崩されつつある。嘆かわしいことだ。
0458デフォルトの名無しさん2011/07/10(日) 22:23:44.91
>>454
マルチキャストとブロードキャストは違うんじゃね?
パソコンサンデーはブロードキャストだよね
0459デフォルトの名無しさん2011/07/10(日) 22:37:12.22
>>458
ipベースのマルチキャストではないけど。。。
言葉の意味を考えると1対Nなので
TV放送は全てマルチキャストじゃないの?
0460デフォルトの名無しさん2011/07/10(日) 22:55:19.78
無差別なのでTV放送(ブロードキャスト)はブロードキャスト(放送)です。
0461デフォルトの名無しさん2011/07/10(日) 22:58:29.15
>>459
マルチキャストは1:N、ブロードキャストは1:∞ みたいな感じ
と覚えとくといいと思う
0462デフォルトの名無しさん2011/07/10(日) 23:14:54.34
>>460
ごめんそうだね。。。
馬鹿だ俺
0463デフォルトの名無しさん2011/07/10(日) 23:34:09.23
受信料とられるん?
0464デフォルトの名無しさん2011/07/13(水) 20:24:07.81
WinSockでrecvを実行した場合に

-----------------------
7330 : recv(7330) = 0 ms
13242 : recv(35562) = 0 ms
22320 : recv(22320) = 200 ms
-----------------------
(戻り値:recv(受信長) = 所要時間)

となった環境でJavaのInputStream.read()をしてみると全受信まで50msほどでした。
そこでrecv毎にrecv(all)して受信のバッファリングなどしてみたのですが、結果は変わらずでした。
APIを直接叩くよりInputStream.read()のほうが速いのはなぜなんでしょうか?
0465デフォルトの名無しさん2011/07/13(水) 20:35:50.97
はいそうです
0466デフォルトの名無しさん2011/07/13(水) 20:54:59.71
>>464
ソケットの設定による。
デフォルトでrecvの中でちょっと待つようになってる。
待たないように設定してみるといい。
0467デフォルトの名無しさん2011/07/14(木) 03:06:37.65
>>466
ack周りかなと思い、それっぽいオプションをsetsockoptで色々設定してみたのですが変わらずでした...
もうちょいヒントを頂けると助かります
0468デフォルトの名無しさん2011/07/14(木) 10:03:30.52
ノンブロックにすればよくね?
0469デフォルトの名無しさん2011/07/14(木) 11:25:55.01
>>466の言っている遅延タイマがまさに200ms。
Winsockのrecvの馬鹿チョン仕様。
04704642011/07/14(木) 22:09:23.33
>>468
やってみましたがダメでしたorz

>>469
Nagleアルゴリズムの事であれば無効の試行済みです。
0471デフォルトの名無しさん2011/07/15(金) 22:58:02.53
信頼性の高いマルチキャストプロトコルで
実装が簡単なのって何がありますか?
0472デフォルトの名無しさん2011/07/17(日) 09:10:13.62
>>464
いっそ、Javaの標準ライブラリが何をやってるのか、ソースコードを調べてみたら?
JDK に付属する src.zip にJava部分が、「Java SE 6 JDK Source Code」に C/C++ 部分があると思う。
04734642011/07/18(月) 00:54:34.43
>>472
そんな物があったのとは!
やってみます。ありがとうございました
0474デフォルトの名無しさん2011/07/20(水) 11:49:04.57
time.nist.govと同期がとれないと起動できないソフトを使用期限解除して
使うようにするにはどうしたらいいですか?
http://www.dotup.org/uploda/www.dotup.org1808412.zip.html
0475デフォルトの名無しさん2011/07/20(水) 12:01:15.76
>>474
time.nist.govを買い取って、好きな時刻に設定すればいい。
0476デフォルトの名無しさん2011/07/20(水) 12:50:02.17
NTPサーバを用意してhostファイルでtime.nist.govにそのIPアドレスを指定する
0477デフォルトの名無しさん2011/07/20(水) 14:48:41.35
>>474
逆アセしてそのチェックして分岐させているところを書き換えるといいよ
0478デフォルトの名無しさん2011/07/20(水) 14:50:14.36
winsockのsend関数で
char buf[100]のものを送るとしたら実際に送られるデータは何バイトになるのですか?
0479デフォルトの名無しさん2011/07/20(水) 14:56:00.83
>>478
それにTCPヘッダとIPヘッダを足した大きさ
それぞれのサイズは忘れた
0480デフォルトの名無しさん2011/07/20(水) 15:13:20.37
なるほどありがとうございます
0481デフォルトの名無しさん2011/07/20(水) 17:24:56.66
どの層を気にしているかによるが、
データリンク層のヘッダにも注意。
0482 忍法帖【Lv=12,xxxPT】 2011/07/20(水) 17:42:59.21
>>478
64 + strlen(data)
0483デフォルトの名無しさん2011/07/25(月) 08:49:02.56
>>478
環境や状況による。
Ethernetなら+TCPヘッダ+IPヘッダ+MACフレームになる。
PPPoE経由でPPTPVPN使ってたりすると、さらに幾つもヘッダがつく事になる。
他のTCPやUDP通信とまとめて、一つのIPパケットにのる場合もある。
0484デフォルトの名無しさん2011/07/25(月) 10:57:00.71
>>483
>他のTCPやUDP通信とまとめて、一つのIPパケットにのる場合もある。

こんなことあるのか?
0485デフォルトの名無しさん2011/07/25(月) 11:15:33.24
ありえねーって突っ込もうとしたけど、>>483特製トンネルならばありうるから止めた。
0486デフォルトの名無しさん2011/07/25(月) 11:39:48.33
「他のsend関数でカーネルに渡したデータと一緒に」
ならTCPでは有りうる。
0487デフォルトの名無しさん2011/07/25(月) 11:44:54.64
>>486
UDPも入ってるから、その可能性は却下。
0488デフォルトの名無しさん2011/07/25(月) 11:53:01.80
誰がどう言ったかとか興味ない。
>>478の質問に即してレスした。
0489デフォルトの名無しさん2011/07/25(月) 16:10:21.68
>>487
TCPでは って言ってんだろ・・・
0490デフォルトの名無しさん2011/07/25(月) 16:12:23.06
> 他のTCPやUDP通信とまとめて、一つのIPパケットにのる場合もある。
0491デフォルトの名無しさん2011/08/05(金) 00:00:54.77
既にハンドシェイクされて確立されたTCPコネクションがあって
そこにパケットを入れ替えるのではなく追加するというのは可能なのですか?
任意のパケットをNICに入れるのはこの際問題にしなくていいです(それは出来る)
TCPプロトコルがいまいちよくわからない
パケットをそのまま入れればいいって問題じゃないですよね?
ACKとかシーケンス番号とかも揃えないといけない?
となるとACKの区切りを検出して、自分のデータのACKのやりとりを丸々入れないけないのですかね?
0492デフォルトの名無しさん2011/08/05(金) 00:16:12.93
TCPハイジャックだっけ
0493デフォルトの名無しさん2011/08/05(金) 00:25:12.33
>>491
そうです 以上
0494デフォルトの名無しさん2011/08/05(金) 00:26:16.72
めんどくさそうだから別の方法でやろう
0495デフォルトの名無しさん2011/08/05(金) 00:35:28.95
難しそうなので僕には出来ませんだろ
0496デフォルトの名無しさん2011/08/05(金) 00:53:09.47
難しいことをやり遂げるのが主目的じゃない
簡単な方法があるならそれを使うまで
パケットを直接入れる方が簡単だと言うなら別だけど
0497デフォルトの名無しさん2011/08/05(金) 09:03:59.82
せやな
0498デフォルトの名無しさん2011/08/05(金) 17:17:11.92
>>491
簡単にはできない。
TCPストリームのデータを中間者が増やした時点で、それ以降のACK/SEQがずっとズレっぱなしになるので、
任意のデータを入れたが最後、その後の通信を全部加工して送らなければならない。

ftpに対応したNATルータがまさにそれをやっている。
0499デフォルトの名無しさん2011/08/05(金) 17:25:53.75
へ?
0500デフォルトの名無しさん2011/08/05(金) 18:05:39.59
>>496
>>494に難しいだけで簡単だって。
スループット上げるのは容易ではないけども。
0501デフォルトの名無しさん2011/08/05(金) 18:33:11.54
全部TCP/UDPパケットをいったん別のソケットにリダイレクトする方が簡単だろ?
一旦正規のソケットに仲介させることで中身をいじるのは簡単になる

1.接続要求がきたら自分のListenポートに修正
2.本来のポートに普通にコネクションを張る
3.自分のソケットから本来のポートに対するパケットのソースアドレスを元に戻す
4.以後はそのパターンでソースとデスティネーションを書き換え続ける

これで完全に仲介したソケットが完成して、本来の接続プログラムが
リモホを参照してもちゃんと元のリモホとして認識されるはず
これでいけると思うんだけど間違ってるかな?
この方法で問題になるのが自分でconnectやacceptする部分であらかじめポート番号を決定できた方が都合がいいんだけど
Winsockってそういうことは可能なんだっけ?
0502デフォルトの名無しさん2011/08/05(金) 18:57:47.69
一生懸命説明してるとこ悪いけど、

> 既にハンドシェイクされて確立されたTCPコネクションがあって

という前提なので。
0503デフォルトの名無しさん2011/08/05(金) 19:03:04.84
>>502
パケットを挿入するという前提があるので、その条件を入れただけですよ
0504デフォルトの名無しさん2011/08/05(金) 19:16:52.10
その前提と条件がどう関係するんだよ。

よくわかってないなら、変な条件つけなきゃいいのに...。
0505デフォルトの名無しさん2011/08/05(金) 19:24:52.51
>>504
こういうスレではあらかじめかなり条件を絞って質問しないと
毎回毎回、知識ひけらかし君が、その部分をまずやれとか意味不明なことを言い出して
それはとっくに出来てるんでとか言うと以後レスしなくなるという
そういう経験ばかりしてきてるんで
無駄なやり取りを減らすために条件を絞るくせがついてるですよ
0506デフォルトの名無しさん2011/08/05(金) 20:03:49.59
>>501からの流れ
誰が誰やらわからんw
0507デフォルトの名無しさん2011/08/05(金) 21:49:57.24
妖しそうなことやりたいんじゃないの?
0508デフォルトの名無しさん2011/08/05(金) 21:50:38.63
>>505
>毎回毎回、知識ひけらかし君が、その部分をまずやれとか意味不明なことを言い出して
>それはとっくに出来てるんでとか言うと以後レスしなくなるという

自分のやったことと、前提条件がちゃんと説明できてないからだろ。
0509デフォルトの名無しさん2011/08/05(金) 22:33:40.45
>>507
妖しいことも出来ない奴がネットワークを語るなよ
そんなレベルの奴に用はねーし
逆にそのレベルに達してきて怪しいことをやったことが無い奴なんて居ない
0510デフォルトの名無しさん2011/08/05(金) 23:23:28.65
ホメラレモセズ
クニモサレズ
サウイフモノニ
ワタシハ
ナリタイ
0511デフォルトの名無しさん2011/08/17(水) 01:52:36.11
おれにはできない。
どういう状況でそんなことやる必要があるのか
知りたい。
0512デフォルトの名無しさん2011/08/17(水) 11:27:32.60
>>501
それは別のネットワークになるので駄目です。
0513デフォルトの名無しさん2011/08/18(木) 22:05:34.40
Socket.Send メソッド (Byte[], SocketFlags)
Socket.Send メソッド (IList<ArraySegment<Byte>>, SocketFlags)
のSocketFlagsの存在が何故あるのかが良く解らないんです。
SocketFlags.Noneを指定するのなら
Socket.Send メソッド (Byte[])
でイイのではないかなぁと思うのですが、サンプル求めてググッてみても
SocketFlags.Noneを指定するのが過半なので、どうしてかな〜と疑問に思い質問です。
なんで?
0514デフォルトの名無しさん2011/08/19(金) 00:11:39.24
Windows上で特定のポートに帯域制限を掛けるプログラムを
C++で組みたいのですが、何から勉強していいかわかりません・・・
何かいい本かサイトを紹介してくれませんか。

スキルとしては、画像やテキスト処理のコマンドラインプログラムを
C++で書ける程度です。
0515デフォルトの名無しさん2011/08/19(金) 01:09:58.09
>>514
どういう方法でやろうとしているの?
特定のwindowsサーバにインストールして、そのサーバの下にいるwindowsPCに帯域制限をかけたいの?
それともwindowsPCにインストールして、インストールしたwindowsPCのみに帯域制限かけたいの?

賢い人達はLINUX使うと思う。

まあ、どういう方法をとるにしろ、
デバドラまで入り込まないと無理だぞ。

今日も眠れぬ青画面の世界までようこそ。

WELCOME!WELCOME!WELCOME!
0516デフォルトの名無しさん2011/08/19(金) 02:47:41.32
>>512
そうらしい、実際にやってみたがループバックは物理的なネットワークが違うものとして扱われるらしくリダイレクト出来ない。
パケットをいじるだけで同じPC内でプロキシをするのは無理らしい。
しかし、苦労したけど結局プロキシする方法を発見して出来たからもういいのだ。
0517デフォルトの名無しさん2011/08/19(金) 09:44:30.60
>>514
標準でQoSに対応しているので、有る程度はレジストリ設定だけで
制限できるんだけど、あくまで作るのが目的なの?

作るなら、フィルタドライバとして作るだけだけど。
0518デフォルトの名無しさん2011/08/19(金) 10:13:26.00
>>515
きもすぎwwwwwwwww
0519デフォルトの名無しさん2011/08/19(金) 19:18:23.78
>>515
>それともwindowsPCにインストールして、インストールしたwindowsPCのみに帯域制限かけたいの?
それです。

>>517
目的達成できるなら手段は問わないです。

具体的にはネットワークカメラを走らせていまして、
プロバイダの30GB/日のUL転送量制限に引っ掛からないように転送量を測って、
20GB超えたら速度制限、25GB超えたらそのポートを遮断
日付が変わったら累積リセット制限解除、ということをしたいのです。

制限を超えるのは極稀な日なので、四六時中制限掛けるのは避けたいですし
LAN同士の転送はカウント外にしたいので、ネットワークカメラのポートだけを監視したいわけです。
0520デフォルトの名無しさん2011/08/19(金) 19:44:57.73
格ゲーだとフレーム単位でキャラ操作するつわものいるけど
そういった人を満足させるネトゲって可能?
0521デフォルトの名無しさん2011/08/19(金) 19:50:42.91
ネット対戦できる格ゲーならあるけど、そういう話じゃなくて?
0522デフォルトの名無しさん2011/08/19(金) 20:24:59.54
フレーム単位で通信する必要ないから可能。
0523デフォルトの名無しさん2011/08/19(金) 21:06:34.70
>>519
それって速度制限というか、絶対量制限しないといけないんじゃないの?
1フレームの転送量を計って、制限量に達するまでに何フレーム送れるか計算したら?

webcam -> localhost:8000 -> internet
みたいな感じでlocalhostさんに一度データを送って、localhostさんがwebcamの
データを外に中継だけするようにしたらどう?
0524デフォルトの名無しさん2011/08/20(土) 01:28:49.55
>>520
不可能
小足見てから昇龍とか無理
0525デフォルトの名無しさん2011/08/20(土) 01:31:40.55
ざ 残像だとっ!
0526デフォルトの名無しさん2011/08/20(土) 03:24:37.45
>>520
地球の裏側まで光速で何秒かかるか計算してみるといい。
理論最速値でもそこまでの速度しか出ないということに驚愕しろ。
0527デフォルトの名無しさん2011/08/20(土) 08:14:59.99
>>519
TCP/UDPプロキシでも使ったほうが手っ取り早いんじゃね?
0528デフォルトの名無しさん2011/08/20(土) 08:15:55.13
>>520
可能。ただし1フレームがネットワークのディレイより長い必要がある。
0529デフォルトの名無しさん2011/08/20(土) 09:59:38.11
フレーム制御だとACKタイムアウトで再送とかされて大量にフレームが来るから
帯域制限を掛けるなら当然、同じフレームは不達として落としてやらないといけないから複雑
0530デフォルトの名無しさん2011/08/20(土) 10:04:44.02
一番簡単な方法はAPIフックだろうね
send recvをフックして遅延を掛けてやればいい
ただ、この方法だと100%のソフトを制御出来る保障がないけど
100%制御がしたいとなるとring3では無理
つまりカーネルモード(ドライバ)の領域に入らないと制御は出来ない
0531デフォルトの名無しさん2011/08/20(土) 10:13:07.93
一番、簡単確実なのは>>523だろ。最適解が出てるんだから、オナニーするの止めろよ。
0532デフォルトの名無しさん2011/08/21(日) 19:26:09.84
C#でsocket使おうと思い質問です。
参考にしたのは
ttp://dobon.net/vb/dotnet/internet/downloadusesocket.html
なのですが、
//受信する
byte [] resBytes = new byte[1024];
System.IO.MemoryStream mem = new System.IO.MemoryStream();
while (true){
int resSize =sock.Receive(resBytes, resBytes.Length,System.Net.Sockets.SocketFlags.None);
if (resSize == 0)
break;
mem.Write(resBytes, 0, resSize);
}
の部分がうまく動作しません。
while一週目で全文受信したのち、2周目でresSize 0がこないのです。
ずっとsock.Receiveのところで固まってしまいます。なにか足りないのでしょうか?
オツムの足りない私めにご教示お願いします。
0533デフォルトの名無しさん2011/08/21(日) 19:43:01.85
resSize 0 ってまず来ないと思うよ
0534デフォルトの名無しさん2011/08/21(日) 20:23:57.84
もう忘れたけど、相手がクローズしたら 0 になるんじゃ?
0535デフォルトの名無しさん2011/08/21(日) 22:30:09.31
>>533
Vista以降はcloseするとFINを送る前に0パケットを送信する

>>532
というわけでclose以外で0バイトの受信が来る事はない。
TCPはデータの到達は保障してくれるけど区切りまでは保障してくれない。
だからTCP通信で必須になるのがデータサイズを相手に通知する作業なの

HTTPプロトコルだと、まず\r\n\r\nでヘッダの終わりを通知して
ヘッダの中のContent-Lengthで後続するデータサイズを明記するという構造でデータサイズを渡してる。

同じようにデータのサイズをあらかじめ通知する方法を自分で考えたプロトコルにも組み込まないといけない。
そうすることで何バイト受信すればいいかがわかるでしょ。
0536デフォルトの名無しさん2011/08/21(日) 22:50:19.66
ナルホド確かに受信文の中に数のデータサイズ部分が居ます。納得しました!
0537デフォルトの名無しさん2011/08/22(月) 02:20:50.65
>>535
そうなんだ
でもそれってUNIX系でいうところの
readの戻り値がゼロ ってやつだよね?
0538デフォルトの名無しさん2011/08/23(火) 00:23:23.89
良く解らんがsetSoTimeout(タイムアウト時間);とかないん?
0539デフォルトの名無しさん2011/08/23(火) 00:47:50.24
もっと参考になるサイトがあるだろうに
0540デフォルトの名無しさん2011/08/25(木) 23:18:57.16
LANケーブルを物理的にハサミでちょん切ったりしたりすると延々受信待ちしてしまいますよね?
socketのReceiveTimeoutは同期の場合にしか使えないようなのですが
非同期の場合はタイムアウトや無応答をどう対処したらいいのでしょう?

if (0 < sock.Available | 0 < resSize)
と、ネットワークから受信した、読み取り可能なデータ量が0ならbreak?
ちがうよなぁ・・・。
0541デフォルトの名無しさん2011/08/26(金) 14:23:25.04
復帰
0542デフォルトの名無しさん2011/08/26(金) 19:26:12.89
UDPとTCPを併用する場合
TCPでの送受信がUDP側に影響を与えることってありますか?
0543デフォルトの名無しさん2011/08/26(金) 20:01:21.09
ないですね。
イーサネットの帯域食うくらいの通信をTCPでしてない限り。
100%ないと思っていいです。
0544デフォルトの名無しさん2011/08/26(金) 20:03:25.09
いやあるね
0545デフォルトの名無しさん2011/08/27(土) 02:26:14.91
(`ハ´) ないあるね。
■ このスレッドは過去ログ倉庫に格納されています