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

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

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2012/10/31(水) 17:05:08.29
主にソケットに関しての質疑応答スレッドです。

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

前スレ
ネットワークプログラミング相談室 Port28
http://toro.2ch.net/test/read.cgi/tech/1334736934/

関連スレ
ネットワークプログラミング雑談
http://toro.2ch.net/test/read.cgi/tech/1235800707/
0194デフォルトの名無しさん2013/06/02(日) 09:34:05.28
何バイト送られて来るかわからない通信でselect→1バイトずつreadと言うのはやるべきじゃないってmanに書かれてたけどどうするのが一番効率的なんでしょう。
mtuの値を取得してその値-フレーム分をreadするのでしょうか?
0195デフォルトの名無しさん2013/06/02(日) 10:54:39.80
そりゃ 1MB 受け取るのに百万回繰り返さなきゃいかんようではお世辞にも効率いいとは言えまい
ノンブロッキングモードにして適当に大きなサイズ (8KB とか 64 KB とか) で読めばいい
0196デフォルトの名無しさん2013/06/03(月) 01:05:59.71
ノンブロッキングにする必要はない。
0197デフォルトの名無しさん2013/06/03(月) 01:16:29.85
selectしているのはブロッキングさせたくないからで、selectの後に受信データより多いバッファ分読み込もうとしたらブロッキングしちゃうからノンブロッキングで読み込む方が良さそうな気がするけど何か見落としあったりします?
0198デフォルトの名無しさん2013/06/03(月) 01:24:07.02
> しちゃう

ダウト
0199デフォルトの名無しさん2013/06/03(月) 01:56:25.17
ブロックするだろ
0200デフォルトの名無しさん2013/06/03(月) 02:00:17.97
しないだろ
0201デフォルトの名無しさん2013/06/03(月) 02:05:28.99
>>199
しない
実験してみるといい
0202デフォルトの名無しさん2013/06/03(月) 02:05:39.31
うん。やっぱしないね>>199は忘れて
0203デフォルトの名無しさん2013/06/03(月) 03:59:52.42
1バイトでもデータがあればね
0204デフォルトの名無しさん2013/06/03(月) 11:23:03.45
selectした後の話だからね。>>197
0205デフォルトの名無しさん2013/06/03(月) 11:26:58.12
select後
受信データが1以上でバッファはデータ以上の大きさで読み込むと?
受信データが無いのに読み込むと?
0206デフォルトの名無しさん2013/06/03(月) 11:33:03.05
馬鹿じゃなかと?
0207デフォルトの名無しさん2013/06/03(月) 11:41:45.21
ゴカイうまかっちゃ
0208デフォルトの名無しさん2013/06/03(月) 12:12:09.02
むろみさんは海に還れ
0209デフォルトの名無しさん2013/06/03(月) 23:50:05.47
あんたドライバー刺すわよ
02101922013/06/08(土) 23:51:12.09
かなり自己解決したっぽい
プロセスを起こすタイプのマルチスレッドサーバの現代版サンプル(他)↓
http://www.v6pc.jp/jp/upload/pdf/socket-sample-20121203.pdf
いとぢゅん氏が絡んでいたやつっぽいので多分信用に足る

で、Winsockにおいてプロセスにソケットを渡す方法↓
http://app.m-cocolog.jp/t/typecast/114340/102386/category/3335520
プロセスの終了を何の工夫も無くWaitForMultipreObjects()で待つと64プロセスが上限になるが、
そこはそれ、WaitForMultipreObjects()で64プロセス待つスレッドを64スレッド待つ、とかいう
多段構成が考えられる(いや知らんけど多分、

WinsockはGUIとの共存に適した非同期インタ──フェ──スも有するが、
とりあえずそこまでウィンドウズべったりにしなくとも、
select()かWsaPoll()だけでもマルチスレッドサ─バをなんとか構成できるのではないか(適当)
02111922013/06/09(日) 00:01:04.61
ちなみに、WinsockではデフォルトでFD_SETSIZE=64だが、
socket()は平気でこれより大きいfd番号を返してくる

ていうか、現代のOSではLinuxだろうがWindowsだろうがFD_SETSIZEの制限に特に意味はなく、
FD_ISSET()の第一引数には 0..max{ socket()が返した値 } + 1 というの連番を与えるのではなくて、
socket()が返した数値(FD_SETSIZEより大きく成り得、かつ離散的)を配列かvectorにでもとっておいて、
その値を直接与えるのが正しいっぽい
上の現代版サンプルでもそうなっている(つまり>189のやり方は古い疑い有り)
0212デフォルトの名無しさん2013/06/09(日) 07:07:01.75
何言ってるか分からないが、その現代版サンプル(謎)でも fd + 1 になってるじゃねーか
0213デフォルトの名無しさん2013/06/09(日) 07:21:28.43
>>212
そこはそうだが、
http://x68000.q-e-d.net/~68user/net/c-echo-2.html
における
 166: for ( i=0 ; i<FD_SETSIZE ; i++ ){
 167: if ( FD_ISSET(i, &target_fds) ){
が、
http://www.v6pc.jp/jp/upload/pdf/socket-sample-20121203.pdf
の「複数の socket を生成するデュアルスタック対応サーバプログラム」では
 for (i = 0; i < smax; i++) {
  if (FD_ISSET(s[i], &rfd)) {
になってるねん(s[]にはsocket()が返した値が入っており、 smaxはs[]の要素数+1
0214デフォルトの名無しさん2013/06/09(日) 09:30:05.98
>>213
何を言いたいのか分からない

FD_SETSIZEを超えたらまずいというのならその通り。
下のURLの方は、

>> if (s[smax] >= FD_SETSIZE) {

でFD_SETSIZEを超えるものを除外してるから、
s[smax]がFD_SETSIZEを超えることはない

離散的だのベクターだのは意味不明
0215デフォルトの名無しさん2013/06/09(日) 13:20:01.15
>>214
話を込み入らせてしまって申し訳ないですが、
>> if (s[smax] >= FD_SETSIZE) {
これは少なくともWinsockでは不要ていうか、
>socket()は平気でこれ(FD_SETSIZE)より大きいfd番号を返してくる (211)
という事実があるので、削除して試した

実際、あるとgetaddrinfo()で列挙されたlisten可能ポート(うちの環境では
s[0] = 116, s[120]=120となった)が全てそのif文で除外され、
bind()やlisten()まで行き着かない。削除するとうまくいく(クライアントとつながり、"hello ::1"とか出る)

>FD_SETSIZEを超えたらまずいというのならその通り。
「何が」FD_SETSIZEを超えたらまずいのかいまいちどお考えいただきたい
FD_ISSET(a, b)の第一引数aが超えたらfd_set構造体をオーバーランするからまずい、というのが第一義だが、
しかし、>213の上のリンク先と、>213の下のリンク先では、第一引数に書かれている内容が異なるのですじゃ
02162152013/06/09(日) 13:22:58.77
訂正。
誤1: getaddrinfo()で列挙されたlisten可能ポート
正1: getaddrinfo()で列挙されたlisten可能ソケット
誤2: s[0] = 116, s[120]=120となった
正2: s[0] = 116, s[1]=120となった
02172142013/06/09(日) 17:26:56.22
一応「何が」について答えておくと、ファイルディスクリプタ番号。
fd_set構造体をオーバーランしたらまずい、という理解で合ってる。
>>213 の上の引用と下の引用の第一引数は同じなので、何言ってるかわからない。
0218デフォルトの名無しさん2013/06/09(日) 17:51:44.47
>>211
> socket()が返した数値(FD_SETSIZEより大きく成り得、かつ離散的)を配列かvectorにでもとっておいて、
> その値を直接与えるのが正しいっぽい
> 上の現代版サンプルでもそうなっている(つまり>189のやり方は古い疑い有り)

根本的に理解してないな。
>>189と同じ事を言っておいて、古い疑いありとはw
仕様と仕様を満たすための実装方法の区別がつかない人みたい。
実装方法で考えないと仕様が理解できない。
0219デフォルトの名無しさん2013/06/10(月) 11:24:49.53
私はselectは使わない、絶対に。
0220デフォルトの名無しさん2013/06/10(月) 11:30:49.49
絶対ニダ
0221デフォルトの名無しさん2013/06/15(土) 12:03:09.61
>>217>>218
はいはい御託は>189をWinsockで動かしてから言ってね&#9825;

BSDソケットでは、ファイルディスクリプタ番号がFD_SETを超えることは無いから>189のコードで良い
0〜FD_SETまでの中に、必ずsocket()で作ったlisten中のソケットがある
Windsockでは違う
0222デフォルトの名無しさん2013/06/15(土) 15:40:20.49
>>221
> Windsock
ってのは, BSD ソケット API を Windows で実装したものって理解してたんだが違うのか?
つか,
> BSDソケットでは、ファイルディスクリプタ番号がFD_SETを超えることは無い
保証は何処にある?
0223デフォルトの名無しさん2013/06/15(土) 15:58:13.05
FD_SETじゃなくてFD_SETSIZEの事言ってるんだろうけど
そんなもの使うのヤメレ
0224デフォルトの名無しさん2013/06/15(土) 15:59:06.31
保証されてるのはFD_SETSIZE未満の記述子に対してだな。
しれっとウソつくなよ。>>221
0225デフォルトの名無しさん2013/06/15(土) 16:46:01.43
>>222
> > Windsock
> ってのは, BSD ソケット API を Windows で実装したものって理解してたんだが違うのか?

違う。似て非なるもの。意味不明の改変もある。
0226デフォルトの名無しさん2013/06/15(土) 16:46:47.76
>>225
>>221は馬鹿でよく分かってないので間違ったこと書くのは仕方ない。
0227デフォルトの名無しさん2013/06/16(日) 12:00:56.26
windsockってなんだwinsock2のことかね
0228デフォルトの名無しさん2013/06/17(月) 12:46:20.67
>>227
1も2もどっちも嫌い
0229デフォルトの名無しさん2013/06/23(日) 03:27:09.95
別物なんだよなあ…ところどころ似てるけど全然違うから紛らわしい
0230デフォルトの名無しさん2013/07/03(水) NY:AN:NY.AN
質問です。
Winsockを使っています。
一度通信を終えた後に再度通信を行おうとすると、sendをacceptが認識してくれません。
bind,listen関数は正常に動作しています。
クライアント側は完全に再起動、サーバーはwhileで使いまわしています。
原因に心当たりのある人教えてください
0231デフォルトの名無しさん2013/07/03(水) NY:AN:NY.AN
>sendをacceptが認識してくれません

認識するわけなかろう
02322302013/07/03(水) NY:AN:NY.AN
>>231
済みません。仰る通りでした。
connectの戻り値は0でクライアント側は繋がっていると認識しているようです。
サーバー側を消すとエラーが出てくるので間違い無いと思います。

サーバー側はacceptを使っているスレッドを消していない時は2つ以上の接続であっても、上手く動作します。
クライアント側が再接続する場合もちゃんと動きます。
しかしスレッドを再起動した時には一つ目の接続から認識しません。
変数は毎回初期化しています。
0233デフォルトの名無しさん2013/07/03(水) NY:AN:NY.AN
サーバーはwhileで使い回してるのにスレッドを再起動?
状況がよくわからんな
0234デフォルトの名無しさん2013/07/03(水) NY:AN:NY.AN
closeし忘れ?
0235デフォルトの名無しさん2013/07/03(水) NY:AN:NY.AN
>>232
ちゃんとListenしなおしてる?
0236デフォルトの名無しさん2013/07/04(木) NY:AN:NY.AN
listenしなおしってなんだよ
しっぱなしでいいだろ
いちいち再listenとかどこのBASICモドキだよ
0237デフォルトの名無しさん2013/07/04(木) NY:AN:NY.AN
accept に渡してるソケットを accept の戻り値で書き換えてるとか?

accept の戻りのソケットは 接続発生毎に別物だから
変な使いまわしからすると 「接続は受けた けど クライアントとの通信が出来てない」 ってなことになる
02382302013/07/05(金) NY:AN:NY.AN
>>233,236
考えてみればlistenしっぱなしで良かったです;
設定を弄る時に排他処理が必要かと思い、止めようとしてました

>>234,5
再lisetn,closeはしていると思います。

>>237
有用な情報ありがとうございます!
以下のような処理をしてるので大丈夫だとは思いますが、調べてみます。

listen(--);
-初期化処理-
while(1){
dstSocket[id] = accept(----);
if(-1 != dstSocket[id]){
--------
id = DecideNewId();
}
}
0239デフォルトの名無しさん2013/07/09(火) NY:AN:NY.AN
これは肝心なところを隠して、どうでもいいところだけ書くダメな質問の典型だな
全体に意味不明だから、もう少し勉強してから出直すほうがいいと思う
0240デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
ほとんどのバグは本人が関係ないと思って端折ってるところに存在する
そもそも肝心なところがどこか判ってるプログラマはむしろバグらない
0241デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
なんでこうセンスの無い人間がプログラミングなんかやるのか
すべて駆逐したい
0242デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
9割5分くらいのPGが消えてしまうじゃないか
0243デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
104期生ってどのくらい巨人になれるの?
0244デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
web(HTTP)の普及のせいで
ネットワークを利用するアプリの質が極端に下がった
退化しまくり
0245デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
なんでもWebサービス。まあ便利だけどね。
0246デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
webサービスは機種依存性をなくしたりアプリのインスコの手間を省いたりDLL地獄回避のメリットがあると言われていたが
結局ブラウザのバージョン依存で地獄とか同じ過ちを繰り返してるとしか
0247デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
俺の言ったwebサービスはWebブラウザは関係ないけどね
0248デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
P2P掲示板の同期方法はどうやればいいですか?
基本が一対一の通信なのに全体で同じデータを受け取れるのはむずかしくないですか?
0249デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
通信速度が上がったから、HTTPのオーバーヘッドが気にならんからなぁ

>>248
P2Pで全体ってどういう事を言ってるのかしらんが
全体で同じデータを受け取る必要はないだろ
0250デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
WebサービスってWSDLとかの話だろ、ブラウザ関係ねえw
0251デフォルトの名無しさん2013/07/10(水) NY:AN:NY.AN
ソケットでhttpクライアント作ってみたけど意外に簡単すね
でも企業面接でhttpの質問のみで落とされますた
0252デフォルトの名無しさん2013/07/11(木) NY:AN:NY.AN
java の質問で拾ってもらいました10年前
0253デフォルトの名無しさん2013/07/11(木) NY:AN:NY.AN
TCPのパケットの問題で落ちたわ…
0254デフォルトの名無しさん2013/07/11(木) NY:AN:NY.AN
>>248
難しくは無い。
全体に同じデータを送る必要があるなら、全体に同じデータを送るだけ。
非常に単純な話だよ。
0255デフォルトの名無しさん2013/07/11(木) NY:AN:NY.AN
実はUDPの方が転送効率は良いんです。TCPは糞です。
http://ascii.jp/elem/000/000/712/712158/
0256デフォルトの名無しさん2013/07/11(木) NY:AN:NY.AN
>>255
tcp6に採用されるような論文書かないと説得力全くない。
特殊な状況でしか効率良くないプロトコルじゃあ...
0257デフォルトの名無しさん2013/07/11(木) NY:AN:NY.AN
TCPが効率悪く見えるのは通信が1対1のときのを測定してるからだよな
多対多の通信を想定したプロトコルなんだから
0258デフォルトの名無しさん2013/07/11(木) NY:AN:NY.AN
TCPって思いっきり1対1の通信を想定したプロトコルじゃねーか。
0259デフォルトの名無しさん2013/07/11(木) NY:AN:NY.AN
故47氏がTCPを何十倍も超える高速通信を実現したとか聞いたが
0260デフォルトの名無しさん2013/07/11(木) NY:AN:NY.AN
TCPが回線スループットの何十分の1の速度しか出ないなんて事は無いから
言ってることが明らかにおかしい
0261デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
UDPは一方向の無手順通信
無手順だから早いってだけでハマらんようにね
0262デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
既存ファイル転送プロトコルに比べて大して変わらない性能で何のインパクトもなかった(当時)。
0263デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
出たなMulticastTCPお化け!
0264デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
SCTPのマルチホーミング構成をとっているときに
クライアント-プライマリサーバからはHEARTBEAT
の送信・応答があるんだけど、セカンダリサーバの
ほうってプライマリからのハートビートインフォメーションに
乗せるんじゃなくてセカンダリサーバからHEARTBEAT
返すことってSOCKOPTのパラメタ設定とかで可能?
0265デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
>>260
複数セッション束ねるとか、方法はあるでしょ
0266デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
>>260
TCPはRTT依存するし、パケットロスに対する速度低下率が高すぎる。
0267デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
>>264
dynamic multihomingが有効なら管理されてるpathの死活を把握してないといけないから、
セカンダリでもheartbeatによるpath管理が行われているはず。
フリーの実装ならRandall Stewartさんが関わっていたFreeBSDが信頼性あるんじゃないか。

>>266
http://image.itmedia.co.jp/l/im/news/articles/1206/12/l_moto_ssbp.jpg
みると、最初からwindow最大化したTCP4とRTT性能は大差ないように思う。
ack管理が閾値ベースである問題は解消してるけど、
そんなのは10年以上前からあるし。
0268デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
無罪判決後、47氏の夢   2012年  『Winnyの金子氏が夢見る次世代高速ネットの世界』
ascii.jp/elem/000/000/712/712158/
>金子:本当にTCPがボトルネックなんですよ。みなさんあまり気付いていないですけど、
>SilverBulletで動作させてみると楽勝で10倍くらいの通信速度が出るんですよ。ヘタすると100倍くらい出ますから。
0269デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
>>258
多対多だおω
0270デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
>>258はTCP層だけしか見てないから仕方ない
0271デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
TCPコネクションが <自IPアドレス, 自ポート番号, 他IPアドレス, 他ポート番号>という
組(tupple)でモデル化されることは、このスレ住人にとっては常識だと思う。

で、TCP層の利用者(user)であるアプリケーションの視点からは、
TCPコネクションは相手アプリケーションとの間の「1対1」関係に見えるし、同時に
TCPコネクションの集合を扱うTCP層の提供者(provider)であるTCPスタックの視点からは、
自集合と多集合との間の「多対多」に見える。
0272デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
ベストエフォート側のネットワークで、
みんな帯域を譲りあいながら使ってるわけだからさ、
じゃないとslow-startとか必要ないわけよ。
0273デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
>>266
>パケットロスに対する速度低下
それは確かにそうだね
0274デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
>>271
ふつう、全単射を「多対多」とは言わんわな。
0275デフォルトの名無しさん2013/07/12(金) NY:AN:NY.AN
言わないな
0276デフォルトの名無しさん2013/07/13(土) NY:AN:NY.AN
TCPを多対多とか言う奴はUMLの多重度も正しく書けないだろ
0277デフォルトの名無しさん2013/07/13(土) NY:AN:NY.AN
輻輳を意識したプロトコルなんだから
1対1のことだけ考えてる訳ではないよ
0278デフォルトの名無しさん2013/07/13(土) NY:AN:NY.AN
>>277
全くその通りだが、それは論点ではない
0279デフォルトの名無しさん2013/07/13(土) NY:AN:NY.AN
速度低下の原因が輻輳であるならば
1対1の場合なら速度低下は起きない
と言っているということになる
それではいったい47氏の主張と
どこが違うと言えると言うのか
0280デフォルトの名無しさん2013/07/13(土) NY:AN:NY.AN
何が言いたいのか伝わって来ない
0281デフォルトの名無しさん2013/07/13(土) NY:AN:NY.AN
流れぶった切って宣伝です
C++で通信ライブラリのようなものを作っております
よかったらお試しください
http://ichishino.nobody.jp/
0282デフォルトの名無しさん2013/07/13(土) NY:AN:NY.AN
>281
頑張ったところを教えて
0283デフォルトの名無しさん2013/07/13(土) NY:AN:NY.AN
どっかのTCP/IPスタックがお馬鹿ってだけじゃあ
0284デフォルトの名無しさん2013/07/14(日) NY:AN:NY.AN
>>281
これは酷い
某技術書のサンプルコードとほとんど同じコードばかりじゃねえかw
0285デフォルトの名無しさん2013/07/14(日) NY:AN:NY.AN
WinSockで通信プログラム作ってるんですけど
ポート1つで通信するとした場合
ホスト側でソケット2つ用意してクライアント2人と繋げたいんですけど
どうしても片方のソケットにしか二人分のデータが飛んでこないんですけど
どうしたらいいですかね
0286デフォルトの名無しさん2013/07/14(日) NY:AN:NY.AN
マヌケな発言はやめてくれ
力が抜ける
0287デフォルトの名無しさん2013/07/14(日) NY:AN:NY.AN
まず服を脱ぎます
0288デフォルトの名無しさん2013/07/14(日) NY:AN:NY.AN
このスレに来ていいレベルじゃないな
0289デフォルトの名無しさん2013/07/14(日) NY:AN:NY.AN
いつからこのスレがレベルの高いスレだったと錯覚している?
0290デフォルトの名無しさん2013/07/14(日) NY:AN:NY.AN
俺が来た時から
0291デフォルトの名無しさん2013/07/14(日) NY:AN:NY.AN
誰も高いなんて言ってないんだが...
0292デフォルトの名無しさん2013/07/14(日) NY:AN:NY.AN
>>289
安心しろ
君がいることがレベルが高くない証明だ
0293デフォルトの名無しさん2013/07/14(日) NY:AN:NY.AN
俺とお前と
■ このスレッドは過去ログ倉庫に格納されています