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

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

■ このスレッドは過去ログ倉庫に格納されています
0001ftp-data2007/08/07(火) 01:47:35
主にソケットに関しての質疑応答スレッドです。

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

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

関連スレ
Java ネットワークプログラミング 【教えて!】
http://pc11.2ch.net/test/read.cgi/tech/1086238859/
0002ftp-data2007/08/07(火) 01:48:11
過去スレ:
Port18 http://pc11.2ch.net/test/read.cgi/tech/1171029896/
Port17 http://pc8.2ch.net/test/read.cgi/tech/1148944560/
Port16 ttp://pc8.2ch.net/test/read.cgi/tech/1136005644/
Port15 ttp://pc8.2ch.net/test/read.cgi/tech/1128088448/
Port14 ttp://pc8.2ch.net/test/read.cgi/tech/1118469143/
Port13 ttp://pc8.2ch.net/test/read.cgi/tech/1109793931/
Port12 ttp://pc5.2ch.net/test/read.cgi/tech/1102427855/
Port11 ttp://pc5.2ch.net/test/read.cgi/tech/1096187183/
Port10 ttp://pc5.2ch.net/test/read.cgi/tech/1090385857/
Port9 ttp://pc5.2ch.net/test/read.cgi/tech/1080658835/
Port8 ttp://pc5.2ch.net/test/read.cgi/tech/1073560271/
Port7 ttp://pc5.2ch.net/test/read.cgi/tech/1063035045/ ★行方不明
Port6 ttp://pc5.2ch.net/tech/kako/1052/10521/1052106444.html
Port5 ttp://pc2.2ch.net/tech/kako/1040/10402/1040220302.html
Port4 ttp://pc3.2ch.net/tech/kako/1034/10342/1034236536.html
Port3 ttp://pc3.2ch.net/tech/kako/1023/10233/1023359282.html
Port2 ttp://pc.2ch.net/tech/kako/1006/10062/1006258198.html
Port1 ttp://pc.2ch.net/tech/kako/970/970344582.html
0003ftp-data2007/08/07(火) 01:50:30
図書コーナー:
UNIXネットワークプログラミング〈Vol.1〉ネットワークAPI:ソケットとXTI
 http://www.amazon.co.jp/exec/obidos/ASIN/4894712059/
 そのソースコード
 http://www.unpbook.com/src.html
詳解TCP/IP〈Vol.1〉プロトコル
 http://www.amazon.co.jp/exec/obidos/ASIN/4894713209/
詳解TCP/IP〈Vol.2〉実装
 http://www.amazon.co.jp/exec/obidos/ASIN/4894714957/
詳解TCP/IP〈Vol.3〉トランザクションTCP, HTTP, NNTP, UNIXドメインプロトコル
 http://www.amazon.co.jp/exec/obidos/ASIN/4894716674/
TCP/IPによるネットワーク構築
 〈Vol.1〉原理・プロトコル・アーキテクチャ
  http://www.amazon.co.jp/exec/obidos/ASIN/432012054X/
 〈Vol.3〉クライアント‐サーバプログラミングとアプリケーション
  http://www.amazon.co.jp/exec/obidos/ASIN/4320028007/
  Linux/POSIXソケットバージョン
  http://www.amazon.co.jp/exec/obidos/ASIN/4320120841/
  Windowsソケットバージョン
  http://www.amazon.co.jp/exec/obidos/ASIN/4320029992/
0004ftp-data2007/08/07(火) 01:51:49
マスタリングTCP/IP RTP編
 http://www.amazon.co.jp/exec/obidos/ASIN/4274065618/
Linuxソケットプログラミング?ネットワークプログラミングにおける実践技法
 http://www.amazon.co.jp/exec/obidos/ASIN/4894714671/
Webプロトコル詳解?HTTP/1.1、Webキャッシング、トラフィック特性分析
 http://www.amazon.co.jp/exec/obidos/ASIN/4894715414/
WinSock2.0プログラミング
 http://www.amazon.co.jp/exec/obidos/ASIN/4797306882/
猫でもわかるネットワークプログラミング
 http://www.amazon.co.jp/exec/obidos/ASIN/4797323604/
IPv6ネットワークプログラミング
 http://www.amazon.co.jp/exec/obidos/ASIN/4756142362/
Visual Basicではじめるネットワークプログラミング超入門
 http://www.amazon.co.jp/exec/obidos/ASIN/4839917523/
0005ftp-data2007/08/07(火) 01:54:23
URL抜粋:
★規格
RFC 日本語版リスト
 http://www5d.biglobe.ne.jp/~stssk/rfcjlist.html
JPNIC RFC関連リンク集
 http://rfc-jp.nic.ad.jp/link/
RFC Editor
 http://www.rfc-editor.org/
HTMLなRFC (セクションを直に示すのに便利)
 http://www.freesoft.org/CIE/RFC/
RFC 2616 "Hypertext Transfer Protocol -- HTTP/1.1" 日本語訳
 http://www.studyinghttp.net/cgi-bin/rfc.cgi?2616
IANA Well known port numbers
 http://www.iana.org/assignments/port-numbers
0006ftp-data2007/08/07(火) 01:55:29
★プログラミング
C10K ヘヴィーロードサーバ
 http://www.kegel.com/c10k.html
C10K ヘヴィーロードサーバ(日本語訳)
http://www.hyuki.com/yukiwiki/wiki.cgi?TheC10kProblem
MSDN
 http://msdn.microsoft.com/library/en-us/dnsitehelp/html/tochelp.asp
Raw IP Networking FAQ
 http://www.whitefang.com/rin/
Java で packet capture
 http://netresearch.ics.uci.edu/kfujii/jpcap/doc/
Randomness Recommendations for Security
 http://www.faqs.org/rfcs/rfc1750.html
BoostSocket
 http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?BoostSocket
The Code Project - Internet & Network programming
 http://www.codeproject.com/internet/
ネットワークプログラミングの基礎知識 (問題ありのサイト?)
 http://X68000.q-e-d.net/~68user/net/
0007ftp-data2007/08/07(火) 01:55:59
★ツール類
ethereal - http://www.ethereal.com/
Wireshark - http://www.wireshark.org/
tcpdump - http://www.tcpdump.org/
Windump - http://netgroup-serv.polito.it/netgroup/tools.html
WinPcap - http://www.winpcap.org/
pathchar - ftp://ftp.ee.lbl.gov/pathchar/
pchar - http://www.employees.org/~bmah/Software/pchar/
Packetyzer - http://www.networkchemistry.com/products/packetyzer/
libevent - http://www.monkey.org/~provos/libevent/

★プロトコル
TTCP
 http://www.sean.de/Solaris/ttcp.html
 http://www.kohala.com/start/ttcp.html
UDP Hole Punching
 http://homepage3.nifty.com/toremoro/p2p/firewall.html

★IP, TCP実装
http://www.iti.fi/documentation/miniip.html
http://www.sics.se/~adam/uip/
http://www.codeguru.com/Cpp/I-N/network/tcpip/article.php/c5447/
http://www.geocities.jp/bruce_teller/security/garakuta.htm
0008ftp-data2007/08/07(火) 02:18:34
テンプレの変更点
・関連スレURLを記載(前スレ >>9 THX)
・RFC 2616 日本語訳URL更新(前スレ >>7 THX)
・C10K問題 日本語訳URL追加(前スレ >>483 THX)
・まとめサイトURL削除(makimo.to サービス終了のため)

上記以外は前スレと同じテンプレで立てさせてもらいました。
追加・補足等あったらよろしく。
0009デフォルトの名無しさん2007/08/07(火) 22:18:48
乙
0010デフォルトの名無しさん2007/08/08(水) 16:24:26
ttcpを使って、UDPデータ(14M)をLANインターフェイスから送信してみたんですけど・・・
rtl8139D → 12Mbps
3Com 3c905c → 12Mbps
※いずれも送信側の数値

RTLは性能良くないとは聞いてたんですけど、3Comもこんなもんなの?(´Д`)
ifconfig 情報では、100baseTXって出てるのに・・・
0011デフォルトの名無しさん2007/08/08(水) 23:00:33
もしその Mbps が mega bytes per second のことを言ってるんなら、ほぼ限界値じゃない?
100BaseTX って 100 mega bits per second だし
12 M bytes = 96 M bits
0012デフォルトの名無しさん2007/08/08(水) 23:11:11
100メガショック!ネオジオといっても100bitsなのと一所だな
0013デフォルトの名無しさん2007/08/09(木) 00:03:13
>>11
の言うとおりでした、申し訳ない。
ソース見ると、ttcpが計測した速度の単位は、byte per second でした。
0014デフォルトの名無しさん2007/08/09(木) 23:41:01
> Visual Basicではじめるネットワークプログラミング超入門
> http://www.amazon.co.jp/exec/obidos/ASIN/4839917523/
VBでSocketを使ったプログラミングを勉強したいのですが、
この本の代わりになるような本はないでしょうか。
どこも品切れで・・・。
0015142007/08/11(土) 22:54:17
隣町の本屋で見つけることができました。
どうも失礼しました。
0016デフォルトの名無しさん2007/08/13(月) 22:59:49
MacAddress destMac = {0x00, 0x17, 0x9A, 0xB3, 0x9E, 0x16};
と設定したとき
struct sockaddr_ll destAddrには何を突っ込めばいいのですか?

流れは

1 socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)
2 以下を設定
destAddr.sll_family = htons(PF_PACKET);
destAddr.sll_protocol = htons(ETH_P_ALL);
destAddr.sll_halen = 6;
destAddr.sll_ifindex = 2; (ioctlで取得した値と仮定してください)

3. sendto()
この流れで基本基本的にL2でデータ流せますよね?

0017デフォルトの名無しさん2007/08/15(水) 01:35:19
すみません、質問させてください。
不特定多数のアクセスがあるFTPサーバがあったとして、アクセスしてきたIPアドレス毎に、
例えば過去10分の間に何度サーバとのコネクションを張ったかだとか、同一のIPアドレスが
複数のコネクションを張っているか否かだとか、コネクションを張った時間と、
切断した時間を取得するようなことができるプログラムをCで組むようにいわれたのですが、
具体的にどのような手法でそれが実現できるのか皆目見当がつかず途方に暮れています・・。
大変申し訳ないのですが、何かアドバイスをいただけないでしょうか・・。
どうぞ皆様のお力をお貸しいただけますようお願いいたします。
(Fedora Core4でgccを使っています。)
0018デフォルトの名無しさん2007/08/15(水) 01:43:17
>>17
パケットみれ

以上
0019デフォルトの名無しさん2007/08/15(水) 01:56:19
>>17
まず、FTPサーバ自身の設定を調べ、アクセスログを出力してるか確認する。
出力してなければ、ログを出力するように適切に設定する。
あなたの作成するコマンドは、FTPサーバの出力するログを解析する。
ログはテキストファイル(たぶん)なので、あとはまあ威張る。

ログの情報には限りがあるし、要件を満たさなければ>>17のいうとおり
パケットをみるしかないけど自分で作るのはたいへん。
その場合でもパケット解析を行うオープンソースのアプリでも探してきて、
そいつから情報をもらうフロントエンドだけ書けばいいんじゃないかな?

アクセスログとかでググって調べてみれ。
0020デフォルトの名無しさん2007/08/15(水) 01:58:20
失礼
×>>17のいうとおり
○>>18のいうとおり
0021デフォルトの名無しさん2007/08/15(水) 02:28:39
ログの情報が足りないなら、ftpd改造してもいいね
0022172007/08/16(木) 01:44:26
遅くなってすみません。皆様アドバイスありがとうございます。

>>18
きっとそれが究極なのでしょうけれど、残念ながら実装する為の知識と力量、そして時間が
間違いなく不足しています、ごめんなさいorz

>>19
なるほど。
おっしゃる通り、FTPサーバが常時吐き出すログをなんらかの方法でプログラム内で取得して、
そこから必要な情報をいただいて処理することで実現できるかもしれませんね。
具体的にFTPサーバがどのようなアクセスログを吐き出すのか、まずはそこから調べたいと思います。
どうしてもログの情報が足りなかったら、パケット解析ソフトからいただくか、21氏の提案してくださった
方法を検討してみたいと思います。本当にどうもありがとうございました。

>>21
ftpdの改造ですか。
私なんかの力量ではかなり難しいと思いますが、もしサーバの吐き出すログの情報が足りなければ、
ひとつの方法として考えてみたいと思います。
アドバイスありがとうございました。
0023デフォルトの名無しさん2007/08/16(木) 01:53:04
>>22
簡単だろ、どうせエラーなんか気にしなくいいんだし
TCPとFTPのプロトコルだけ知ってりゃいいだけの
話だよな?

なぜやらんさっさとパケットみて好きなもの作れよ

これ以上何も作らないでここで質問したらお前は
ゴミとしてVIPPER未満のクソとして扱うぞ?
0024デフォルトの名無しさん2007/08/16(木) 03:21:42
>>22 は多分パケット見る手段自体知らないと思うが
0025デフォルトの名無しさん2007/08/16(木) 07:24:34
簡単だよ
http://homepage2.nifty.com/spw/tips/PacketDump.html
0026デフォルトの名無しさん2007/08/17(金) 07:08:57
>>17の質問内容から見て多分学生の宿題だろうから
(もしくは新人研修)
>>23のやり方が正解なんだろうね
問題提出者は>>25の手法で この後にftpのプロトコルの
勉強させるつもりなんだろうね。

>>17が 上司からFTPの設定を指示されてるのに
自分で作ろうとしているアホなら どうしよ・・・・・
0027デフォルトの名無しさん2007/08/17(金) 09:03:57
最終的に、一定時間当たりの最大接続数や、最大接続時間に制限を加えたい
という要求があり、それら設定項目がftpdに備わっていないならば、
簡単なフィルタリング・プログラムを書く必要があるだろう。
そういう前提なら、パケット読み取るプログラムを書く。
しかし、>>17がほしがる情報は、ふつうのftpdならログで吐けるし、
>>17がほしがる情報を元にフィルタリングするような機能は、ふつうのftpdなら備えている。
「ログ解析による実装」か「パケット・フィルタを実装」か、出題者に相談した方がいいんじゃないの。
0028デフォルトの名無しさん2007/08/17(金) 10:26:09
その方式の選択理由も含めての出題かも試練。
0029デフォルトの名無しさん2007/08/17(金) 12:26:30
VC6のMFCを使ってチャットツール作ってるわけですが
通信の部分の実装でMFC使ってるんだから素直にMFCのCSocket使うべきか
普通のsocket使うべきか悩んでます。
皆さんならどうしますか?
なんかCSocketは評判悪げ。
0030デフォルトの名無しさん2007/08/17(金) 12:54:53
http://anti.bne.jp/upload/updata/up0685.swf
0031デフォルトの名無しさん2007/08/17(金) 13:02:49
>>29
Winsock2を直接叩いて頑張れ。>>4の本がよい。
0032デフォルトの名無しさん2007/08/19(日) 10:49:09
MFC使ってるならわざわざ再開発する必要も無いだろ。
そもそもMFC使ってる時点で(ry
0033デフォルトの名無しさん2007/08/21(火) 07:46:40
板違いかもしれないが、他に聞く場所が解らなかったんでここで聞かせてください。
epoll_ctl(2)のmanに、
EPOLLRDHUP (カーネル 2.6.17 以降)
ストリームソケットの他端が、コネクションの close 、またはコネクションの書き込み側の shutdown を行った。 (このフラグを使うと、エッジトリガの監視を行う場合に、通信のもう一端が閉じられたことを検知するコードを非常に簡潔に書くことができる。)
と書かれてるのですが、
2.6.17以降のカーネルのものを使っていても、この値が定義されてません。
誰かこの値を使ってる人いますか?
0034デフォルトの名無しさん2007/08/21(火) 09:55:57
ディストリは何よ?
ヘッダファイルは別パッケージに分かれているんじゃないか?
0035デフォルトの名無しさん2007/08/21(火) 13:38:16
>>29
CSocketは元々同期処理のソケットを非同期処理にし
それを更に同期処理を模倣している無駄な奴なので
それ使うぐらいなら普通のソケット使う方が良いだろう。
でも、非同期処理にしただけのCAsyncSocketならば使う価値はある。
0036デフォルトの名無しさん2007/08/21(火) 15:32:12
>>34
ubuntu6.10使ってます
0037デフォルトの名無しさん2007/08/22(水) 09:22:01
>>33
それは__USE_GNUの拡張ありでコンパイルされたカーネルじゃないとない。
POLLHUP使ってください。こっちのshutdownも検知する以外は一緒。
0038デフォルトの名無しさん2007/08/22(水) 14:03:16
>>37
ありがとうございます。
>>__USE_GNUの拡張ありカーネルでないとつかえない
って知りませんでした。
POLLHUP使ってみます。
0039デフォルトの名無しさん2007/08/24(金) 04:13:20
AN HTTPの最新版が欲しくて中田昭雄氏のサイト行ってみたけど見れない…
誰か最新版の投下お願いします…
0040デフォルトの名無しさん2007/08/24(金) 04:44:46
vectorにあるぜ
0041デフォルトの名無しさん2007/08/24(金) 04:53:42
vectorにあるのは古いverですね。(1.37b)
最新は中田氏サイトのgoogleキャッシュ見る限りだと1.42pみたいです。
0042デフォルトの名無しさん2007/08/24(金) 08:16:28
>>41
ググるとほぼトップに来るが?
http://www.forest.impress.co.jp/lib/inet/servernt/server/anhttpserver.html
0043デフォルトの名無しさん2007/08/24(金) 09:37:55
>>42
杜かw
0044デフォルトの名無しさん2007/08/24(金) 11:50:34
>>42
ありがとう。助かったよ。
0045デフォルトの名無しさん2007/08/26(日) 23:22:07
VB6.0のWinsockコントロールを使っているのですが、うまくいきません。
教えてgooでも質問してみたのでマルチポストになりますが、返事がこないので改めてこちらで質問させてください。

助言をどうかお願いします。もうAPIのWinSockの方を使った方がいいでしょうか?
以下が自分なりに纏めた今の状況です

アンチウィルスソフトは導入していない。また、ファイアウォールを外している。

ルーターの設定で、ポート転送->使うポートの転送先を自PCのプライベートアドレスにしている。プロトコルはTCP/UDP。TCPのみにしても結果は変わらず。
ルーターで設定したポートで​http://www.cman.jp/network/support/port.html​;で検査するとホスト=***.**.**.*** ポート=***** にアクセスできました。と出る。
ルーターで設定していない他のポートで試したら失敗する。
また、検査したときにサーバー側ソフトではConnectionRequestイベントが発生した。

接続先のRemoteHostを127.0.0.1、プライベートIP、マシン名にすると繋がる。
グローバルIPを入れると、サーバー側プログラムを起動せずに上記の接続を試みたときのエラー番号と同じ、10061。意味は「接続が拒否されました。」

サーバー側でのWinsockプロパティの設定は
Winsock.Protocol = MSWinsockLib.ProtocolConstants.sckTCPProtocol
Winsock.LocalPort = *****
そして、待機状態にさせています。
Winsock.Listen()

クライアント側でのWinsockプロパティの設定は
Winsock.Protocol = MSWinsockLib.ProtocolConstants.sckTCPProtocol
Winsock.RemoteHost = ***.**.**.***
Winsock.RemotePort = *****
そして、接続要求をださせています。
Winsock.Connect()
0046デフォルトの名無しさん2007/08/26(日) 23:28:34
ルータの内側から、ルータの外側用アドレスでアクセスしてみたってこと?
0047デフォルトの名無しさん2007/08/26(日) 23:32:33
っwireshark
あとルータのログも見とけ
0048452007/08/27(月) 00:50:11
>>46
そうです。もしかしてできないんですか?
>>47
見てみます。
0049デフォルトの名無しさん2007/08/27(月) 07:46:30
中から来たパケットを逆納豆テーブル見て
折り返してくれるかどうかはルータによる。
0050デフォルトの名無しさん2007/08/27(月) 22:59:15
ネバツイテ
折り返そうしても出てこないことあるよなぁ
0051デフォルトの名無しさん2007/08/29(水) 01:24:10
あるある
0052デフォルトの名無しさん2007/08/30(木) 22:04:12
Winsockにてサーバアプリケーションを作成しています。
メインスレッドで、クライアントからの接続待受スレッド(スレッドA)を起動し、
クライアントからの接続ごとに送受信用スレッドを起動しています。

スレッドA:クライアントからの接続待受スレッド
 A-1.ソケットの作成、bindやらlistenやら
 A-2.WSAEventSelectでFD_ACCEPTを待つイベントをセット
 A-3.ループを開始し、この中でWSAWaitForMultipleEventsでイベント待ち
 A-4.FD_ACCEPTが来たらacceptしてスレッドBを起動し、接続待ちに戻る

スレッドB:1クライアントごとの送受信スレッド
 B-1.WSAEventSelectでFD_CLODE、FD_READを待つイベントをセット
 B-2.ループを開始し、この中でWSAWaitForMultipleEventsでイベント待ち
 B-3.FD_READが来たらrecvで受信し、電文の終端文字を受信したらレスポンスをsendで返す
   電文の終端文字が無ければループ先頭に戻り、次のFD_READを待つ
   recvでSOCKET_ERRORが返ったらループ終了
 B-4.FD_CLOSEが来たらソケットをクローズしてループ終了
 B-5.ループを抜けたらスレッドを終了

クライアント:
 C-1.ソケットを作成してコネクト
 C-2.sendしてレスポンスを待つ(recv)
 C-3.レスポンスを受信したら切断して終了

0053522007/08/30(木) 22:04:46
続きです。
>>52のような処理を組んでいます。
わからない点がいくつかあるのでご教授ください。特にB-3のあたり。

1.B-3にて、100byte受信したいが、recvで70byteまでしか受信できなかった場合、
  残りが受信可能になったらFD_READのイベントが再度発生してくれるのでしょうか?
  簡単な検証をしてみたら、発生しているようですが、
  場合によってはイベントが発生せず受信バッファにだけ溜まるということはあるのでしょうか?
2.B-3にて、recvでWSAEWOULDBLOCKとなった場合、次のFD_READを待つのが正解でしょうか?
3.B-3にて、レスポンスをsendで返すのはrecvの直後で行ってよいのでしょうか?
  それともFD_WRITEが来たら?FD_WRITEをどう使うのかよくわかりません・・・。
4.アプリ終了時にスレッドA,Bを終了させるのに一般的にはどうするのでしょうか?
  どちらもWSAWaitForMultipleEventsで待っているのですが、
  ここで適当なタイムアウトを設定して、アプリ終了フラグを見るとか・・・?
0054デフォルトの名無しさん2007/08/30(木) 23:01:17
1.発生する
2.というか、WSAEWOULDBLOCKが帰ってくるまで
 recvをループで回すほうがいい
3.FD_WRITEは、sendがWSAEWOULDBLOCKを返したときに、
 送信を再開するために使う。つまり,1)recv直後にsend
 2)WSAEWOULDBLOCKがかえってきたら3)FD_WRITEを待って、
 ふたたびsend
4.同時に終了したいときにSetEventされるようはhEventをまつ
0055デフォルトの名無しさん2007/08/30(木) 23:11:47
とにかくしね
0056デフォルトの名無しさん2007/08/30(木) 23:39:25
>>54
recvをループさせるのはrecvが0を返すまででいいんじゃない?
0057522007/08/31(金) 01:14:50
>>54
ありがとうございます。大変勉強になります。

4の回答が少しわかりづらいのですが・・・^^;
イベントオブジェクトをもう1つ用意して、WSASetEventでシグナルにするとか・・・?

>>56
ありがとうございます。
recvからは0が戻るか、WSAEWOULDBLOCKが発生したらrecvを呼ぶのを中断して
再度WSAWaitForMultipleEventsで待てばよいでしょうか?
現状はそうしていますが、これで良いのか判断つかなかったので・・・。
0058デフォルトの名無しさん2007/08/31(金) 02:37:49
つーかさ、1ソケットで1スレッドを占有するなら
本来、ブロッキングソケットで足りるんだよ。
イベントなんか用意する必要も無く。
もちろん、鯖がsendでブロックしている間にもデータが送られてくるような
作り(プロトコル)なら話は変わってくるがね。

で、それで済むところをわざわざEventを使ってるのに
終了シグナルと両方待たなくてどうするのさ。
0059デフォルトの名無しさん2007/08/31(金) 03:16:58
ごめん。
56だけど、recvが0を返すまでってのはブロッキングソケットの終了待ちロジックだ。

ノンブロッキングソケットの場合、受信データがなければエラーになって
WSAEWOULDBLOCKを示す。なので、0は基本的に返らないが、接続終了時には
0を返す場合がある。
なので、>>57のようにループして両方判定しておけばOK。

ブロッキングソケットの場合は、受信データがなければ受信データがくるまで
ブロックする。だから、ブロックしたくなくて、イベント処理をしているなら、
recvのループはまずくて、recv後は必ずFD_READを待たなければいけない。
0060デフォルトの名無しさん2007/08/31(金) 07:16:15
1ソケットごと送受信する以下の4種類のプログラムを作ってみたのですが
1. 2スレッドで同期ソケット
 送信スレッドはキューにたまるのをcondition/event等待ち、sendする
 受信スレッドはrecvで待ち
2. 2スレッドで非同期ソケット
 送信スレッドはキューにたまるのをcondition/event等待ち、sendする
 受信スレッドはselectで待ち、recvする
3. スレッド無しで同期ソケット
 タイマー、ソケットからのイベントなどで定期的にselectで確認して必要なソケットのrecvを行う
 タイマー、ソケットからのイベントなどでキューにたまっているソケットのsendをselectで確認後行う
4. スレッド無しで非同期ソケット
 タイマー、ソケットからのイベントなどで定期的に全てのソケットでrecvを試す
 タイマー、ソケットからのイベントなどでキューにたまっているソケットのsendを行う
Linux/Windowsそれぞれあまり性能差、負荷の差がありませんでした。
通常はどれがいいのでしょうか?
ソケット数は100ぐらいが限度で、メモリ、CPUは問題ない環境です。
0061デフォルトの名無しさん2007/08/31(金) 11:53:08
メンテしやすい方法
0062デフォルトの名無しさん2007/08/31(金) 13:01:07
キューにたまるのを待って send なんてしなくても、キューにためず直接 send しちゃっていいんじゃないかと思うけど。
あと、select は扱えるソケットが 64 個までとか変な制限がある場合があるので、いちおう確認したほうがいいかもしんない。
0063デフォルトの名無しさん2007/08/31(金) 21:14:35
select自体は、あらかじめFD_SETSIZEを128とかに
定義すれば、その制限からは外れるみたいな。
0064デフォルトの名無しさん2007/08/31(金) 21:52:43
スレッドはソケットごとに2個づつ使うので、selectは1socketしか待たないのですよ
なので、スレッドが大量にできるために、必要の無いスレッドはなるべく休止状態にしておきたいのです。

キューに入れるのは送信するのが10GBとかなのと、ヘッダをつけたりしているので、
send途中であふれた場合にどっかに取っておく必要があるのと、ある程度バッファに入れたら送信自体を停止する必要があるため。

スレッドを大量に作るのは定石とは違うのかも。
0065デフォルトの名無しさん2007/08/31(金) 21:58:22
pollでひっぱれよ

0066デフォルトの名無しさん2007/08/31(金) 22:04:35
FD_SETSIZEって変更できたっけ?
0067デフォルトの名無しさん2007/08/31(金) 22:06:21
sendfileしてあとはシラネ、みたいな。
0068デフォルトの名無しさん2007/08/31(金) 22:07:30
Winsock.hの42行から
/*
* Select uses arrays of SOCKETs. These macros manipulate such
* arrays. FD_SETSIZE may be defined by the user before including
* this file, but the default here should be >= 64.
*
* CAVEAT IMPLEMENTOR and USER: THESE MACROS AND TYPES MUST BE
* INCLUDED IN WINSOCK.H EXACTLY AS SHOWN HERE.
*/
#ifndef FD_SETSIZE
#define FD_SETSIZE 64
#endif /* FD_SETSIZE */
0069デフォルトの名無しさん2007/08/31(金) 23:47:58
>>64
そんな設計なら普通にブロッキングモードにしとけば
send は送信バッファが一杯になったら空くまでブロックしてくれるし
recv は受信データが無ければ来るまでブロックしてくれる
select も独自キューも使う意味なし
0070デフォルトの名無しさん2007/09/01(土) 02:08:54
>>69
スレッド・同期スレッドの場合には、sendはソケット内のバッファが開くまでブロックすることは期待しているけど、
送信するデータが無い場合にはブロックしようが無いので、送信データが来るまでビジーループにするわけにも行かないので、
キューを作ってそれが空じゃなくなるのをコンディションなどで待つ必要があると思うのですが。

受信側はそのとおりになってます。実際は受信データがきたら
ヘッダを解析してまとまりごとにデータを纏めて
メインスレッドにイベントを投げて受信したデータを処理しています。

現在4種類とも実装して、設定で切り替えられるようにしていましてどれも動いてはいるのです。
他にもWinsocksだと非同期IO(OverlapedIO/sendmsg)などで実装するなど色々サンプルはみているのですが
実際どれがいいのかは環境依存?

スレッドを大量に立てると高負荷になるし、
タイマーでポーリングすると、タイマー内で処理をする量の制限を掛けるため、
性能がいまいちな場合もあります。

ちなみに、現在のキューは2つの同期制御付きキューを使って、
片方を処理データに、もう片方を未使用のメモリ用に使ってます。
これで、送信データを設定する場合に未使用のメモリの部分に直接ファイルなどから読み込むことにより、
キューへのコピー処理も起きないようにしています。
受信データは未使用メモリのキューから取ってきて、使用中のキューにヘッダ+データが来た時点で入れて処理しています。

最初は同期ソケット+スレッドか、非同期ソケット+非スレッドの2種類になるのかと思ってたのですが、
実際は>>60に加えて受信、送信スレッドそれぞれスレッド無しかどうかも独立に扱えるようにはなっているのです。
でも、結局いろいろ作ってもどれでも変わらないのかも???
0071デフォルトの名無しさん2007/09/01(土) 08:37:43
Windowsの場合、性能的にはIoCompletionPortを使うのがベストと聞いた。
IoCompletionPortは非同期ソケットをベースとするけど、
扱うソケットが増えてもイベントやスレッドの生成自体を少なくできる、らしい。
0072デフォルトの名無しさん2007/09/01(土) 11:06:50
OVERLAPPEDを使うとSend/Recvで扱うバッファをユーザーが先に指定できるので
データの送受信にコピーが要らない。(逆に言えばその辺の管理をこちらがやる)
更にIoCompletionPortでスレッドの管理をやらせると利用可能な最大スレッドも指定できる
・・・という認識だったけど。
0073デフォルトの名無しさん2007/09/01(土) 16:32:00
ネットワークケーブルで繋がったパソコンを遠隔起動させるプログラムを作りたいのですが、
そのために必要なマジックパケットがどのようなものでどのように送信するのかが分かりません
どなたかご存じないでしょうか?
やりたいこと自体は単純で、マックアドレス指定したパソコンの電源を入れるだけです
(フリーソフトのWakeUpみたいな感じです)
ちなみに自分が開発に使用している言語は純粋なC言語です
0074デフォルトの名無しさん2007/09/01(土) 16:48:35
>>73
wakeonlanでググレカス
0075デフォルトの名無しさん2007/09/01(土) 17:20:21
>>74
ありがとうございます!
0076デフォルトの名無しさん2007/09/01(土) 17:34:55
>>74の優しさに全米が嫉妬
0077デフォルトの名無しさん2007/09/02(日) 00:16:34
ところで、
みなさんrecvの最大受け取りバイト数を1にしてループ回すのは極悪だと思ってますか?
それともそれでもいいと思いますか。
0078デフォルトの名無しさん2007/09/02(日) 00:32:49
世の中には実行効率なんかどうでもいい場面ってのがあるから、状況しだいでは別にいいんじゃね
0079デフォルトの名無しさん2007/09/02(日) 00:52:42
それが極悪ならfgetcを繰り返すのも極悪になるぞ
0080デフォルトの名無しさん2007/09/02(日) 01:57:38
>>79
理想的には、例えば'\n'が出てくるまで読む、という非常に1byte recvしたい処理においても
自分で管理のためのバッファを用意し、1byte recvする場合よりも格段に
複雑なバッファリング処理をするほうが正しいってことになってると思うぞ。
http://tangentsoft.net/wskfaq/articles/lame-list.html
の22、Festering in a pool of lameness.ってなってる。
俺はドザじゃないが、昔ドザだったころにこれを見て以来それを頑に守ってきた。
どうでもいいテストプログラムとかを除いて。

>>79
違うぞ。例えば1byteずつ1000byteを読みだす場合、
fgetcを1000回読みだすのは、既にユーザ空間に適切バッファリングされたデータを読みだすので、
システムコールを叩くのは軽く1000回以下。環境依存だが、大抵はこれより
大幅に少ない、1回とか0回(すでに読まれてた)になると思う。
recvを1000回呼ぶのは、システムコールもきっちり1000回叩く。この差は大きい。
0081デフォルトの名無しさん2007/09/02(日) 09:45:10
> recvを1000回呼ぶのは、システムコールもきっちり1000回叩く。

実装依存だろ。頭固いな。
0082デフォルトの名無しさん2007/09/02(日) 13:34:56
>>79
> それが極悪ならfgetcを繰り返すのも極悪になるぞ
実装依存だろうけど, unix 系では通常
fgetc はライブラリ: システムコールのオーバヘッド小
recv はシステムコール: システムコールのオーバヘッド大
なので recv で 1 バイト読み込みループは極悪
0083デフォルトの名無しさん2007/09/02(日) 13:44:46
recvで1コールするとUnix系だと
KernelとUserでメモリコピー毎回発生するぞ?
0084デフォルトの名無しさん2007/09/02(日) 14:36:15
selectを抜けた後呼び出して
中ではバッファリングしてるんだけど
特定の条件をクリアするまでは
読んだことにならないread?表現難しいな
のスケルトンが欲しい。
0085デフォルトの名無しさん2007/09/02(日) 14:42:20
>>84
条件とかかけよぼけが
頃すぞぁぁぁあ?

一人で読み書きするならそもそも
条件なんて勝手に決めろよぼけ
ってはるだろうがーこの糞ピザ野郎が

お前は1000回氏ね
0086デフォルトの名無しさん2007/09/02(日) 15:20:26
>>85
条件なんて案件ごとに違うじゃん
だからライブラリじゃなくてスケルトンって書いたんだってば
愛してるよ
0087デフォルトの名無しさん2007/09/07(金) 15:53:53
超初歩的な問題ですみませんが、どうしても判らないので教えてください。

p2pのネットゲームを作っていまして、
サーバになる方は、ポートを空けて接続を待つのは判るんですが、
空けるポート番号は、1024〜65535の間でしょうか?
それとも、動的/プライベートポートの49152〜65535の間でしょうか?

0〜1023は一般的なポート番号で使わないほうがいいのは判りますし、
1024〜49151は、予約済みポートですから、
ユーザーが自由に使えるということで、49152〜65535を空けるようにしましたが、
たとえは「ひぐらしデイブレイク」では37564など、予約済みポートの範囲内で、
ポートを開放している場合があります。

またクライアント側に割り当てられるポート番号は動的/プライベートポートから
選ばれるみたいで、すでに別のソフトでクライアントとして、そのポートが使われていて、
いざp2pゲームでサーバとして、ポートを開放しようとしたら、空かないことがあるかも知れないですよね。

変な文章ですみませんが、ポートを開く約束事について、良くわかりませんので、
どうか教えてください。
0088デフォルトの名無しさん2007/09/07(金) 16:59:55
>>87
0-1023は使わないほうが良いだろうけど、それ以降のポートが全て決められている
わけでは無いし、星の数ほど存在するソフトが65535のポートで足りると思うか?
思いついたポート番号をググって使われてなさそうなら、使ってしまえ。
と適当な事を言ってみる。

使おうとしたポートをbindさせた時点で既に他のソフトで使われているようなら
エラー出るし、問題無いだろ。
0089デフォルトの名無しさん2007/09/07(金) 18:35:16
>>87
最悪、ユーザが自由に変更できるようにしとけば、ぶつかっても回避できる

参考までに
http://www.iana.org/assignments/port-numbers
0090872007/09/07(金) 20:45:21
早速の返答ありがとうございます。

説明不足でしたが、>>89さんの言うような、ポート番号を入力できるメッセージボックスがあり、
ユーザーが開けたいポート番号を自由に決めれるようになっています。

ただ、そのポート番号を選択できる範囲が、1024〜65535の方がいいのか、
49152〜65535の方がいいのか、わかんないのです。恥ずかしい話・・・

普通、自由に使えるプライベートポートというなら、みんな49152〜65535の範囲でポート開放するのに、
先の「ひぐらしデイブレイク」では37564の予約済みポートの範囲内でポートを開けるし、
あるp2pソフトの使用説明サイトでは、1024〜65535までの間で好きな数を選べると書かれています。

動的/プライベートポートがあるのに、わざわざかち合う可能性のある予約済みポートの範囲を使うのは、
ルーターを使用している環境での、ポート開放に有利になるんじゃないかと、勘ぐってしまいます。
ちなみに、私のネット環境はbフレッツで、回線終端装置から直にLAMケーブルでパソコンにつながっているので、
ルーターのポート開放をしたことが無く、ルーターについてよくわかりません。

あんまり、ポート番号について、気にする必要は無いのでしょうか?
0091デフォルトの名無しさん2007/09/07(金) 20:50:59
もちろん気にした方がいい。
有名どころのポートや、
過去に問題があってセキュリティで睨まれているポートは避ける。

0092デフォルトの名無しさん2007/09/07(金) 22:10:03
攻撃力高そうなケーブルだなLamケーブル
0093872007/09/08(土) 00:20:45
返答ありがとうございます。

>>92さん、すみません。LANケーブルでした。

あと、>>91の書き込みで、
「有名どころのポートや、
過去に問題があってセキュリティで睨まれているポートは避ける。」
と、あるので、自由に使える動的/プライベートポートである49152〜65535の間で、
ユーザーに解放させるポート番号を選択させた方がよろしいでしょうか?

そうなると、なぜ他のP2P通信のゲームやソフトは、予約済みポートの範囲内で、
ポートを開放しているのかがわかりません。自分が見たところ、動的/プライベートポートで
開放しているところより、予約済みポートの範囲で開放しているところが多い気がします。
問題のwinnyも、初期は7747をあけていましたし・・・。

このスレッドの皆さんには常識なのに、こんなことをしつこく聞いて申し訳ないと思いますが、
ユーザーに開放させるポートの選択範囲は、
1024〜65535の方がよろしいのか?
49152〜65535の方がよろしいのか?
どうか教えてください。
本当にすみません。
0094デフォルトの名無しさん2007/09/08(土) 00:23:51
>ただ、そのポート番号を選択できる範囲が、1024〜65535の方がいいのか、
>49152〜65535の方がいいのか、わかんないのです。

個人的には、そういう妙な縛りはイヤだ。
1〜65535を自由に選択できればいいと思う。

そのダイアログが毎回表示されて、ユーザにポートを選ばせるんなら、ちょっと鬱陶しいかもしんない。
適切なデフォルト値を用意しておいて、一般ユーザはそれに触らずに済むようにして、
わざわざ変更したいと思うパワーユーザだけ、設定画面を出して変えればいいと思う。
そういう人は、自分が何やってるか解ってるだろうから、任せとけばいいよ。
0095デフォルトの名無しさん2007/09/08(土) 01:40:17
>>93
多くのアプリが1024〜49151ってのは、49152〜65535にすると、本当に動的に取得してる
アプリやクライアントなどと競合する可能性があるからたまたまタイミングによってサービス
が起動できない可能性を嫌っているんじゃないだろうか。

1024〜49151なら、少なくともマシン/OS設定のチェックをキチンと行えば、実行時のエラー
は最小化できるし、それがたとえ定義済みのポートだったとしても、サービスの運営側と
すれば、自分のマシンに競合アプリが入ってなければ実質的な問題は発生しないので
気にしなくて良い。

もっとも動的といっても、例えばクライアントの使用するポート番号(エフェメラル・ポート)
はOSによって違い、FreeBSDなどは確かに49152〜65535だが、Windowsの場合、
1024-5000が使用されてるみたいなので、厳密な意味での競合回避できるかは分からないし、
心理的なものかもしれないが。
でも、そのような理由で例えばデフォルトは5001〜49151の範囲から定義済みでないものを
選ぶみたいな考えもあるかもしれない。

というわけで、ポートの選択は実際にサーバを立てる人の好みの問題や、
場合によってはファイアフォールなんかとの兼ね合いもあるので、一般にきつくするのは好まれない。
ただ初心者が使う前提のアプリなら推奨値の範囲で縛りを入れておいた
方が後々のトラブル回避点でメリットはあるので、あとはアプリしだいでは。
0096デフォルトの名無しさん2007/09/08(土) 06:44:18
apacheを使わないWebDAVサーバって有ります?
0097デフォルトの名無しさん2007/09/08(土) 11:46:28
動的portとプライベートportが、49152〜65535ってのは決まりごとです。
>>95は甚だしく不当な言明。無知蒙昧。

> 少なくともマシン/OS設定のチェックをキチンと行えば、実行時のエラーは最小化できるし、

に至っては言葉を失う。
0098デフォルトの名無しさん2007/09/08(土) 11:47:53
>>96
http://www.webdav.org/projects/
0099952007/09/08(土) 18:26:23
>>97
申し訳ない。
以前サーバ開発のプロジェクトにいたとき、周りがみんな
この程度の認識だったので、正直甘く考えていた。

これからは気をつける、もうそんな開発の機会もなさそうだけど。
0100872007/09/08(土) 22:47:55
皆さん、ありがとうございます。これらの書き込みを、いろいろ参考にさせてもらいます。

最終的にポート番号の入力ですが、入力ボックスを用意しますが、
ゲームクライアントが最初にログイン画面を立ち上げた際、49152〜65535の間をランダムに、
番号を割り振るようにします。
そこで、IDネーム、パスワード、ポート番号を決定したら、それをログインデータとしてセーブし、
以後、ソフトが立ち上がるたびに、ログイン画面の入力ボックスには、ID、パスワード、ポート番号が、
すでに入力されているようにします。もちろん、この時点で入力ボックスの中身を変更して、ログインしたら、
ログインデータも新しい方に修正されます。
ランダムにポート番号を割り振る時は、49152〜65535の動的/プライベートポートの範囲ですが、
入力できる範囲は、予約済みポートを含めた、1024〜65535の範囲を選択出来るようにします。

こんなもんでどうでしょうか?
0101デフォルトの名無しさん2007/09/09(日) 06:23:53
acceptする方のportは範囲を狭めておかないと、
firewallの設定を全部開けておく必要があることになる。
■ このスレッドは過去ログ倉庫に格納されています