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

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

■ このスレッドは過去ログ倉庫に格納されています
0001UnknownNGNG
主にソケットに関しての質疑応答スレです。

Programming UNIX Socket FAQ (日本語訳)
http://www.kt.rim.or.jp/~ksk/sock-faq/indexj.html

Winsock Programmer's FAQ
http://tangentsoft.net/wskfaq/

過去スレ:
ネットワークプログラミング相談室
 http://pc.2ch.net/tech/kako/970/970344582.html
ネットワークプログラミング相談室 Port2
 http://pc.2ch.net/tech/kako/1006/10062/1006258198.html
ネットワークプログラミング相談室 Port3
 http://pc3.2ch.net/test/read.cgi/tech/1023359282/
ネットワークプログラミング相談室 Port4
 http://pc3.2ch.net/test/read.cgi/tech/1034236536/
0263261NGNG
>>262
つまりできるってことでよろしいですよね?
0264デフォルトの名無しさんNGNG
>263
LinuxのApacheにWindowsのIEで観覧できますか?と同じような話かと
0265デフォルトの名無しさんNGNG
>>261
既にCygwinのgccで通るプログラムがあるならそのままやる方が
楽は楽だろうけど、作ったプログラムを配布しようと思ったら
cygwin1.dllも配布しなきゃとかGPLだから〜とかあるんで、最終的
にどっちでやるかは自分で判断しる。
0266デフォルトの名無しさんNGNG
> GPLだから〜

詳しくないんだがcygwin関連でそういう制約あったっけ?
0267デフォルトの名無しさんNGNG
/*--------------------------WinSockの初期化を行う----------------------------*/
wVersionRequested = MAKEWORD(2, 0); //バージョン 1.1 を要求する
nErrorStatus = WSAStartup(wVersionRequested, &wsaData);

if (atexit((void (*)(void))(WSACleanup))) {//終了時にWinSockのリソースを解放するようにしておく
fprintf(stderr,"atexit(WSACleanup)失敗\n");
exit(-1);
}
if ( nErrorStatus != 0 ) {
fprintf(stderr,"WinSockの初期化失敗\n");
exit(-1);
}

/*-----------------------sdにソケットを作成します----------------------------*/
sd = socket(PF_INET, SOCK_STREAM, 0); //TCPで通信
if(sd == INVALID_SOCKET){
fprintf(stderr,"ソケット作成失敗\n");
}
0268デフォルトの名無しさんNGNG
/*----------------------------サーバの設定-----------------------------------*/
sv_sockaddr.sin_family = AF_INET;//インターネットの場合
sv_sockaddr.sin_addr.s_addr = inet_addr("169.254.185.85");//サーバのIPアドレス
sv_sockaddr.sin_port = htons(PORT);//ポート番号
memset(sv_sockaddr.sin_zero,(int)0,sizeof(sv_sockaddr.sin_zero));

/* 指定のソケットでサーバへコネクトします */
if(connect(sd,(struct sockaddr *)&sv_sockaddr,sizeof(sv_sockaddr)) == SOCKET_ERROR){
fprintf(stderr,"サーバへの接続失敗\n");
}

FD_ZERO(&r_fd);//r_fdを初期化
while(1){
FD_SET(0, &r_fd);//キーボードをr_fdに追加
FD_SET(sd, &r_fd);//fdをr_fdに追加

select(sd+1, &r_fd, NULL, NULL, NULL);

if(send(sd, buf, lstrlen(buf), 0) == SOCKET_ERROR){
fprintf(stderr,"サーバへの送信失敗\n");
}

if(FD_ISSET(0, &r_fd)){
memset(buf, 0, sizeof(buf));
fgets(buf, RECVSIZE - 1, stdin);
send(sd, buf, lstrlen(buf), 0);
}
0269デフォルトの名無しさんNGNG
if(FD_ISSET(sd, &r_fd)){
memset(buf, 0, sizeof(buf));
buf_len = recv(sd, buf, RECVSIZE - 1, 0);

if(buf_len == 0){
break;
}
buf[buf_len] = '\0';
printf("%s",buf);
}



if (buf_len == SOCKET_ERROR ){
fprintf(stderr,"サーバからの受信失敗\n");
}else{
buf[buf_len] = '\0';/* 受信したバッファの後ろにNULLを付加する */
}
}
closesocket(sd);
exit(0);
}
0270デフォルトの名無しさんNGNG
こんなプログラムを組んだのですが、コネクトした時点ですでに
bufにゴミみたいのがまざってしまうのですが、何故でしょうか?
ちなみに、間違ってip書いちゃったけど、気にしないでください。。
0271デフォルトの名無しさんNGNG
connectした時にすでにおかしいと言いながら全文載せるとは何事か
0272デフォルトの名無しさんNGNG
>>270
なんかめちゃくちゃだよ?
selectの後のsendは何?
if (buf_len == SOCKET_ERROR ){
fprintf(stderr,"サーバからの受信失敗\n");
}else{
buf[buf_len] = '\0';/* 受信したバッファの後ろにNULLを付加する */
}
の場所はそこなの?
0273デフォルトの名無しさんNGNG
>>266
cygwin1.dllはGPL。
続ける場合はGPLスレかUnix板のCygwinスレにでも移動して。
0274デフォルトの名無しさんNGNG
>>270
WinSockで

FD_SET(0, &r_fd);
select(sd+1, &r_fd, NULL, NULL, NULL);
if(FD_ISSET(0, &r_fd)){
 memset(buf, 0, sizeof(buf));
 fgets(buf, RECVSIZE - 1, stdin);
 send(sd, buf, lstrlen(buf), 0);
}

これ(標準入力をselectで待つ)できたっけ?
Cygwinのgccならその辺エミュレートしてるから動くだろうが、その場合
WSAStartupとかやる必要ないし。なんかUnix流のやり方とWinSockの
やり方がごっちゃになってるような…
0275デフォルトの名無しさんNGNG
>>274
できない(WSAENOTSOCKを食らう)
0276デフォルトの名無しさんNGNG
ファイルをHTTPで転送するルーチン作ったんだけど、
ファイルをすべて on memory でもっていて転送したとしても、
TransmitFile を使って行うファイル転送にかなわない。
(両方の場合も非同期転送でやってます。)

どうしてこんなに効率いいんだ? > TransmitFile
どんな魔法を使っているんだYO
おまえら、TransmitFileに自作転送ルーチンで勝てた人いらっしゃいますか?
0277デフォルトの名無しさんNGNG
ダブル バッファリングを行わずに、ディスクからファイルを直接転送します。
0278デフォルトの名無しさんNGNG
ユーザーランドへのコピーが一度でも起こると
パフォーマンス的には厳しい。
linuxにもsendfileってのがあるね。
0279278NGNG
>>277
転送したい内容は既にメモリ上でもっているんですが(w

>>278
そうですねよ。。。
究極の回答はLANのデバイスドライバ作ってそこにファイル転送ルーチン仕込めということなのでしょうか?
それともユーザランドでカーネルレベルでのメモリ確保を行って、
そこから転送すればよいのでしょうか? それができるかどうかはなぞですが(w
0280278NGNG
>>279
あう、間違えた 276 です。ごめんなさい。
鬱だ、気晴らしに sim city4でもやろう
0281デフォルトの名無しさんNGNG
> それともユーザランドでカーネルレベルでのメモリ確保を行って、
> そこから転送すればよいのでしょうか?

つまるところそれを肩代わりするのがTransmitFileやsendfile
なのでは?
0282デフォルトの名無しさんNGNG
>>276
非同期転送って、WriteFileExやWSASendのコールバックでやってる?
それで負けるんならお手上げだよなぁ・・・。
0283デフォルトの名無しさんNGNG
HTTPで、BODYだけGETする方法ってありますか?
0284デフォルトの名無しさんNGNG
GET / HTTP/0.9
0285デフォルトの名無しさんNGNG
>>284
0.9でBODYだけ取得できるのは知ってましたが
それって問題無いんですか?
0286デフォルトの名無しさんNGNG
いや・・・0.9をサポートしてるかどうかを心配したほうが・・・
0287276NGNG
>>282
WSASendの非同期でやっています。
Athlon1G Memory512MB の環境で150KB程度のファイルを転送させて、
apache benchで 5クライト1000アクセスで測定した結果、
TransmitFileと自作の転送ルーチンの差が 秒間10アクセス程度の差がでています。
0288282NGNG
>>287
いや、重複I/Oでもイベント使うのとコールバックの二種類あって、
イベントの方だとWaitFor〜のオーバーヘッド分遅いだろうなって思って。
0289デフォルトの名無しさんNGNG
>>288

FAQだけど、socket buffer は大きくしてる?
http://www.asahi-net.or.jp/~vz4h-sruz/memo/ffftp-hack.html
とかが参考になるかも。
0290276NGNG
>>289
知りませんでした(w
で、やってみました。
転送レートが 秒間3〜10ぐらい伸びました。感動しました。

で、結果からなんですが、転送レートにばらつきがあるのが疑問点です。
自宅LANなので他人が回線を使っているわけでないのでほぼ一定でなければおかしいような気がします。
そーゆーものなんでしょうか?

気づいたことは、
通常は 75〜85% ぐらいの負荷なのですが、
転送率が良くなるときにきまってサーバの CPU使用率が 100%振り切っています。

何かOS側、もしくはLANカードのドライバ(カニさん(w) が関係しているのでしょうか。
もう少し検証してみます。。。
0291デフォルトの名無しさんNGNG
カニさんは高負荷時に挙動不審になるとか
linuxのドライバ書きの外人がボヤいてた気がする
0292デフォルトの名無しさんNGNG
どこでCPU使ってるのか、profileしてみたら?
0293デフォルトの名無しさんNGNG
カニさんは自作板で、叩かれてたような気がする
0294デフォルトの名無しさんNGNG
カニって、CPUを使って転送するのか...
0295デフォルトの名無しさんNGNG
カニってうまいよな。
あんなにうまくなければ乱獲されずに済んだのに。
0296デフォルトの名無しさんNGNG
>>290

もし、TransmitFile の場合に、そういう現象が起きてないなら、
作りの問題かもね。
あらかじめ、ワーカスレッドを何十個か必要なだけ作っておいて、
accept後、そいつらに同期send+closeさせてみると多少マシになるかも?
0297276NGNG
>>296
>もし、TransmitFile の場合に、そういう現象が起きてないなら、
>作りの問題かもね。
うわーん(w

>あらかじめ、ワーカスレッドを何十個か必要なだけ作っておいて、
>accept後、そいつらに同期send+closeさせてみると多少マシになるかも?
スレッドプールはすでに導入済みです。
0298276NGNG
ネットワークとは関係ないですが、
ワークメモリを FileMapping してみたら、ちょっとだけ効率が上がりました。
カーネルに(近いレベルで)取得したメモリから
ソケット(カーネル)に書き出せるからかな?

昨日やった実験で少しパフォーマンスが向上したのでご報告。。。
0299276NGNG
>カニさんは自作板で、叩かれてたような気がする
どこでもカニはたたかれますよね。
実は、転送効率を測定するためにベンチを走らせたり、
自作のクラッシャーで攻撃すると Windows OS 自体がクラッシュしたりする
なぞの現象になやんでいたりします。一説にはドライバがくさっているとか。。。

とりあえず、Intel のカード買ってくる予定です(w
これでダメならメモリがやばいかもしれない。。

プログラムと関係ないので sage
0300デフォルトの名無しさんNGNG
その次はTransmitFileのような・・・
0301デフォルトの名無しさんNGNG
>>276
ネットワークプログラムを最近始めたものですが、HTTP転送によるファイル転送(WebDAVじゃなく)を調べているのですが、参考にされたWebサイトありませんか?
また、TransmitFileはWin固有でしょうか?
0302デフォルトの名無しさんNGNG
linuxにもあるよ。名前違うけど
0303デフォルトの名無しさんNGNG
>>299
本当にドライバが腐ってるだけなら
とっくに誰かが安定したものに書き直してるでしょう
おそらく腐ってるのはドライバではなく仕様だと思われ
0304デフォルトの名無しさんNGNG
mmapか。勉強になるのお。
0305276NGNG
>>301
クライアント側でしょうか?
おいらはサーバ作っているんでちょっと違いがあるかもしれないけど、
とりあえず有名どころで、
http://www.studyinghttp.net/index.html
あとは、 RFC とか、そこら辺に転がっているソースとか、
高速化のところは apache2 とか参考にしています。

近々このソースも公開する予定なので、もしよろしければ参考にしてください(w
0306301NGNG
>>305 私もC/Sで考えてます。ありがとう
0307301NGNG
>>305 私もC/Sで考えてます。ありがとう
0308301NGNG
>>305 私もC/Sで考えてます。ありがとう
0309デフォルトの名無しさんNGNG
メモリ上の送信より、mmapの方が早いってのは、理屈から考えるとヘン。
(メモリがswap outされていたとか以外に考えにくい)
メモリを物理メモリにロックした場合と比較してみては?
あと、ソケットにTCP_NODELAY指定はしてあるんだっけ?
0310デフォルトの名無しさんNGNG
>>309
メモリへ載せるための転送も計算に入れてる?
0311デフォルトの名無しさんNGNG
>>309
速い時はCPU利用率が100%になっていると言っているのだから、
copy from memory to memoryがボトルネックになりつつあるのは明らかだが…

Libraryやkernelの中身まで考えたことないんだろうな、>>309は。
データのメモリアライメントも考えたことないのだろうし。
0312デフォルトの名無しさんNGNG
そ、言えば、最近trailer protocolってあんまり聞かないね。
http://deesse.univ-lemans.fr:8003/Connected/RFC/1122/21.html
DMA転送する前にalignmentを調整する必要がないように考えられたのだが。
0313デフォルトの名無しさんNGNG
>>311
>速い時はCPU利用率が100%
ってのは、ドライバがカニだからじゃないの?
よほど小さな単位でsendしてるのでないかぎり、
(普通にmalloc等で確保した領域を使っての)send部分が原因で
CPU使用率が100%になるなんて、見たことないけど?
0314デフォルトの名無しさんNGNG
だからmallocでメモリ確保したらコピーが1回余計に増えるでしょ
0315デフォルトの名無しさんNGNG
あれ?
今回は、ReadFile()の(mallocした領域への)読み込みは、起動直後に
完了していて、転送時の計測のカウントに入らないんじゃなかったの?
0316デフォルトの名無しさんNGNG
socketへの書き込みから始って、networkに流れるまでにも、copyが行なわれる。
それを防ぐために、TransmitFileなんてものがある。
0317デフォルトの名無しさんNGNG
>>316

通常のsocketの TCP->IP->Ether、なんてプロトコルスタックを下るような
動作をせずにショートカットしてるの?

ま、それはともかく、今は、mmap領域とmalloc(中身はGlobalAllocとかだ
よね?)領域を sendした場合の動作の違いについての話なので、
TransmitFileの話は無関係だよね?
0318デフォルトの名無しさんNGNG
>>317
>>314は無視
0319276NGNG
>>309
>あと、ソケットにTCP_NODELAY指定はしてあるんだっけ?
してません。
で、設定してみたところ、あんまりかわらないか、現状以下の数字しか出なかったです。

長いので次の書き込みでベンチを貼り付けます。

0320276NGNG
指定あり
Document Length: 165142 bytes
Concurrency Level: 5
Time taken for tests: 187.694 seconds
Complete requests: 10000
Failed requests: 0
Broken pipe errors: 0
Total transferred: 1653547960 bytes
HTML transferred: 1651457542 bytes
Requests per second: 53.28 [#/sec] (mean)
Time per request: 93.85 [ms] (mean)
Time per request: 18.77 [ms] (mean, across all concurrent requests)
Transfer rate: 8809.81 [Kbytes/sec] received
Connnection Times (ms)
min mean[+/-sd] median max
Connect: 0 7 29.7 6 2948
Processing: 19 87 144.3 82 9093
Waiting: 18 86 144.3 82 9092
Total: 19 93 147.2 89 9106
0321276NGNG
指定なし
Document Length: 165142 bytes
Concurrency Level: 5
Time taken for tests: 177.813 seconds
Complete requests: 10000
Failed requests: 0
Broken pipe errors: 0
Total transferred: 1653637020 bytes
HTML transferred: 1651546184 bytes
Requests per second: 56.24 [#/sec] (mean)
Time per request: 88.91 [ms] (mean)
Time per request: 17.78 [ms] (mean, across all concurrent requests)
Transfer rate: 9299.87 [Kbytes/sec] received
Connnection Times (ms)
min mean[+/-sd] median max
Connect: 0 8 3.5 7 24
Processing: 18 81 40.3 80 3103
Waiting: 17 80 40.3 80 3102
Total: 18 88 40.3 88 3113

あ、これは ab の結果です。。
0322276NGNG
>>313
>よほど小さな単位でsendしてるのでないかぎり、
ソケットのバッファ長は伸ばしているので小さい値で send していないと思います。
それでも、 CPU 70〜80は余裕で行きます。

apache2も同じように CPU を使用するのでそーゆーものなのではないのでしょうか?
なお、IISは速度こそapache2と同じですが、CPU使用率が 50%前後という恐ろしい結果を
出してくれます。 ゲイツマジックの予感。
0323デフォルトの名無しさんNGNG
>>322

指定なしの場合にすでに、ほぼ理論値近い値(NICはGbitとかじゃないよね?)
でてるから、いいんでないの?
CPU使用率問題は、ある程度はカニが原因っぽいから、NIC交換後に再計測
してみるとか。
0324276NGNG
>>323
それが違うんです。。。

apache2 で同じファイルを転送したときの結果
Concurrency Level: 5
Time taken for tests: 159.725 seconds
Complete requests: 10000
Failed requests: 0
Broken pipe errors: 0
Total transferred: 1654330095 bytes
HTML transferred: 1651559264 bytes
Requests per second: 62.61 [#/sec] (mean)
Time per request: 79.86 [ms] (mean)
Time per request: 15.97 [ms] (mean, across all concurrent requests)
Transfer rate: 10357.36 [Kbytes/sec] received
Connnection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.3 0 11
Processing: 25 79 4.6 78 104
Waiting: 24 78 4.6 77 103
Total: 25 79 4.6 78 104

で、理論地をオーバーするような結果がえられるんですよ。。。なぞです。
0325276NGNG
いまさらなんですが、さっきあらためて貼り付けたベンチを見て思ったんですが、

Connnection Times の値の max がオイラのやつはめちゃくちゃでかいですね。
min は apache2 より小さいのに何かある条件かでガクンとひっかかるような
処理が行われているような気がしていました。
ひとつ思い当たる節があるので調査してきまうす。
0326デフォルトの名無しさんNGNG
>>324

>Transfer rate: 10357.36 [Kbytes/sec] received

のことだったら、理論値オーバーには、なってないよね。
100Mbps = 100000000bps = 12207KB
ヘッダその他、オーバーヘッドがあるから、これよりは若干落ちるけれど。
0327デフォルトの名無しさんNGNG
>>326
理論値超えてるって。もうちょっとEthernetプロトコルのお勉強してから書き込もうね。
0328276NGNG
とりあえず、成果物を公開します。。。
http://pc3.2ch.net/test/read.cgi/tech/1043275721/

いまだにカクと処理が落ちるなぞは良くわからないのですが、
ソースや作りたちものを出さずしてなかなか説明しづらいところがあるので、
αテストということで。。。
0329デフォルトの名無しさんNGNG
>>327

超えてないよ。
>>327の理論値って幾つ?いってごらん。嗤ってやるから。
0330デフォルトの名無しさんNGNG
>>327

余計な部分(file I/Oなど)を削ぎ落としての実測をしたことがない?
0331デフォルトの名無しさんNGNG
>>328

とりあえず、アドバイスはこんな感じかな?

細かくWSASend()を発行しない。
(なるべく、ヘッダと本体をあわせて1回のWSASendで送ってしまう)

ソケットバッファを大きくすると、closesocket() でのバッファの
flush 完了待ちが長くなるので、ワーカスレッド側で、closesocket()
まで面倒を見る。
0332デフォルトの名無しさんNGNG
>>331

mmap してる場合は、ヘッダとファイルデータを連続させることは難しいから、
WSASendでWSABUF配列を2つ以上並べる必要があるかもね。
0333デフォルトの名無しさんNGNG
パケットUDPで他PCとデータをやり取りするソフトを作っているのですが
サーバー側はクライアント側からデータが来たってわかる方法はありますか?
recvfromでずっと待ってるわけにはいかないですよね?
0334デフォルトの名無しさんNGNG
何故まっているわけにはいかないのか小一時間問いつめたい。
0335デフォルトの名無しさんNGNG
スレッドを知らないからに1024パケット
0336デフォルトの名無しさんNGNG
>>333

select か WSAAsyncSelect()を使う。
0337デフォルトの名無しさんNGNG
>>334
アプリが固まるから
>>335
知らんから聞いてる
>>336
非同期って奴ですよね?
ちょっとためしてみます。
0338デフォルトの名無しさんNGNG
スレッドを知らないレベルの人間に非同期処理を行わせるのと、
マルチスレッド+同期APIを教えるのはどちらが現実的なんだろうな。
0339デフォルトの名無しさんNGNG
>>338
教える気がないカス野郎はとっとと首吊って下さい。ウザイです。
0340デフォルトの名無しさんNGNG
>>339
教わる気がないカス野郎はとっとと首吊って下さい。ウザイです。
0341デフォルトの名無しさんNGNG
頭がぬるぽなカス野郎はとっとと首吊って下さい。ウザイです。
0342デフォルトの名無しさんNGNG
>>341 ガッ
0343ネタニマジレスNGNG
>>339
質問所と相談室を混同するなよ。
スレルールのどこに 「ぼやき NG」 と書いてある?
0344デフォルトの名無しさんNGNG
>>343
1をよく読みましょうね。
貴様みたいな馬鹿は字も読めないのですか?
ここに来る前に幼稚園から始めて下さい。
0345デフォルトの名無しさんNGNG
>>344
> 貴様みたいな馬鹿は字も読めないのですか?
微妙な日本語・・・。
0346デフォルトの名無しさんNGNG
>>343
つーか、お前の存在がネタだろ、負け犬(w
0347デフォルトの名無しさんNGNG
>>346
正解
0348山崎渉NGNG
(^^)
0349343NGNG
ふ、漏れの崇高な精神はおまいらには理解できなかったようだな。
0350デフォルトの名無しさんNGNG
ネットワークプログラムを今やるなら、CかC++のどちらを
やっていたほうがいいのでしょうか?
0351デフォルトの名無しさんNGNG
そうだな、どっちかというとsocketかな。
javaや.netのはちょっと隠されすぎ。
0352デフォルトの名無しさんNGNG
winsockでもエラーは負って決め打ちしてもいいの?
0353デフォルトの名無しさんNGNG
ヘルプ読めませんか?
0354デフォルトの名無しさんNGNG
>>350
ソケットの勉強をしたい  だ け  なら C でもいいと思われ。
それ以外なら C++ をお勧めします。

>>352
良くない。
詳しくは >>353 の言うようにヘルプを読んで下さい。
0355デフォルトの名無しさんNGNG
結局BSDソケットプログラムは全面的に書きなおさないとwinsockへの移植は無理(逆も無理)
ってことですか。残念。
0356デフォルトの名無しさんNGNG
>>349
理解できないので二度と来ないでください。
0357デフォルトの名無しさんNGNG
>>354

今ならCよりC++を勉強したほうがいいんですね。
Cならリチャードスティーブンスのネットワークプログラム本が
ありますが、C++ではどの本がおすすめでしょうか?
本スレよりネットワーク専門でやってる人の方が詳しそうなので
教えてください、お願いします。
0358デフォルトの名無しさんNGNG
推薦図書/必読書のためのスレッド PART 8
http://pc3.2ch.net/test/read.cgi/tech/1041595397/l50
0359デフォルトの名無しさんNGNG
>>355
APIには互換があるのでソケット以外の部分の絡みでなければ
書き直す必要は無い
0360デフォルトの名無しさんNGNG
>>357
はあ?「Cならリチャードスティーブンスのネットワークプログラム本がある」んなら
C++でも↑でいいじゃん。頭大丈夫?
0361デフォルトの名無しさんNGNG
馬鹿が威勢のいいこといってるな藁
0362デフォルトの名無しさんNGNG
(・∀・)ゲハハハ
■ このスレッドは過去ログ倉庫に格納されています