テンプレの変更点
・関連スレURLを記載(前スレ
>>9 THX)
・RFC 2616 日本語訳URL更新(前スレ
>>7 THX)
・C10K問題 日本語訳URL追加(前スレ
>>483 THX)
・まとめサイトURL削除(makimo.to サービス終了のため)
上記以外は前スレと同じテンプレで立てさせてもらいました。
追加・補足等あったらよろしく。
乙
ttcpを使って、UDPデータ(14M)をLANインターフェイスから送信してみたんですけど・・・ rtl8139D → 12Mbps 3Com 3c905c → 12Mbps ※いずれも送信側の数値 RTLは性能良くないとは聞いてたんですけど、3Comもこんなもんなの?(´Д`) ifconfig 情報では、100baseTXって出てるのに・・・
もしその Mbps が mega bytes per second のことを言ってるんなら、ほぼ限界値じゃない? 100BaseTX って 100 mega bits per second だし 12 M bytes = 96 M bits
100メガショック!ネオジオといっても100bitsなのと一所だな
>>11 の言うとおりでした、申し訳ない。
ソース見ると、ttcpが計測した速度の単位は、byte per second でした。
14 :
デフォルトの名無しさん :2007/08/09(木) 23:41:01
15 :
14 :2007/08/11(土) 22:54:17
隣町の本屋で見つけることができました。 どうも失礼しました。
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でデータ流せますよね?
17 :
デフォルトの名無しさん :2007/08/15(水) 01:35:19
すみません、質問させてください。 不特定多数のアクセスがあるFTPサーバがあったとして、アクセスしてきたIPアドレス毎に、 例えば過去10分の間に何度サーバとのコネクションを張ったかだとか、同一のIPアドレスが 複数のコネクションを張っているか否かだとか、コネクションを張った時間と、 切断した時間を取得するようなことができるプログラムをCで組むようにいわれたのですが、 具体的にどのような手法でそれが実現できるのか皆目見当がつかず途方に暮れています・・。 大変申し訳ないのですが、何かアドバイスをいただけないでしょうか・・。 どうぞ皆様のお力をお貸しいただけますようお願いいたします。 (Fedora Core4でgccを使っています。)
>>17 まず、FTPサーバ自身の設定を調べ、アクセスログを出力してるか確認する。
出力してなければ、ログを出力するように適切に設定する。
あなたの作成するコマンドは、FTPサーバの出力するログを解析する。
ログはテキストファイル(たぶん)なので、あとはまあ威張る。
ログの情報には限りがあるし、要件を満たさなければ
>>17 のいうとおり
パケットをみるしかないけど自分で作るのはたいへん。
その場合でもパケット解析を行うオープンソースのアプリでも探してきて、
そいつから情報をもらうフロントエンドだけ書けばいいんじゃないかな?
アクセスログとかでググって調べてみれ。
ログの情報が足りないなら、ftpd改造してもいいね
22 :
17 :2007/08/16(木) 01:44:26
遅くなってすみません。皆様アドバイスありがとうございます。
>>18 きっとそれが究極なのでしょうけれど、残念ながら実装する為の知識と力量、そして時間が
間違いなく不足しています、ごめんなさいorz
>>19 なるほど。
おっしゃる通り、FTPサーバが常時吐き出すログをなんらかの方法でプログラム内で取得して、
そこから必要な情報をいただいて処理することで実現できるかもしれませんね。
具体的にFTPサーバがどのようなアクセスログを吐き出すのか、まずはそこから調べたいと思います。
どうしてもログの情報が足りなかったら、パケット解析ソフトからいただくか、21氏の提案してくださった
方法を検討してみたいと思います。本当にどうもありがとうございました。
>>21 ftpdの改造ですか。
私なんかの力量ではかなり難しいと思いますが、もしサーバの吐き出すログの情報が足りなければ、
ひとつの方法として考えてみたいと思います。
アドバイスありがとうございました。
>>22 簡単だろ、どうせエラーなんか気にしなくいいんだし
TCPとFTPのプロトコルだけ知ってりゃいいだけの
話だよな?
なぜやらんさっさとパケットみて好きなもの作れよ
これ以上何も作らないでここで質問したらお前は
ゴミとしてVIPPER未満のクソとして扱うぞ?
>>22 は多分パケット見る手段自体知らないと思うが
26 :
デフォルトの名無しさん :2007/08/17(金) 07:08:57
>>17 の質問内容から見て多分学生の宿題だろうから
(もしくは新人研修)
>>23 のやり方が正解なんだろうね
問題提出者は
>>25 の手法で この後にftpのプロトコルの
勉強させるつもりなんだろうね。
>>17 が 上司からFTPの設定を指示されてるのに
自分で作ろうとしているアホなら どうしよ・・・・・
最終的に、一定時間当たりの最大接続数や、最大接続時間に制限を加えたい
という要求があり、それら設定項目がftpdに備わっていないならば、
簡単なフィルタリング・プログラムを書く必要があるだろう。
そういう前提なら、パケット読み取るプログラムを書く。
しかし、
>>17 がほしがる情報は、ふつうのftpdならログで吐けるし、
>>17 がほしがる情報を元にフィルタリングするような機能は、ふつうのftpdなら備えている。
「ログ解析による実装」か「パケット・フィルタを実装」か、出題者に相談した方がいいんじゃないの。
その方式の選択理由も含めての出題かも試練。
29 :
デフォルトの名無しさん :2007/08/17(金) 12:26:30
VC6のMFCを使ってチャットツール作ってるわけですが 通信の部分の実装でMFC使ってるんだから素直にMFCのCSocket使うべきか 普通のsocket使うべきか悩んでます。 皆さんならどうしますか? なんかCSocketは評判悪げ。
32 :
デフォルトの名無しさん :2007/08/19(日) 10:49:09
MFC使ってるならわざわざ再開発する必要も無いだろ。 そもそもMFC使ってる時点で(ry
板違いかもしれないが、他に聞く場所が解らなかったんでここで聞かせてください。 epoll_ctl(2)のmanに、 EPOLLRDHUP (カーネル 2.6.17 以降) ストリームソケットの他端が、コネクションの close 、またはコネクションの書き込み側の shutdown を行った。 (このフラグを使うと、エッジトリガの監視を行う場合に、通信のもう一端が閉じられたことを検知するコードを非常に簡潔に書くことができる。) と書かれてるのですが、 2.6.17以降のカーネルのものを使っていても、この値が定義されてません。 誰かこの値を使ってる人いますか?
ディストリは何よ? ヘッダファイルは別パッケージに分かれているんじゃないか?
>>29 CSocketは元々同期処理のソケットを非同期処理にし
それを更に同期処理を模倣している無駄な奴なので
それ使うぐらいなら普通のソケット使う方が良いだろう。
でも、非同期処理にしただけのCAsyncSocketならば使う価値はある。
>>33 それは__USE_GNUの拡張ありでコンパイルされたカーネルじゃないとない。
POLLHUP使ってください。こっちのshutdownも検知する以外は一緒。
>>37 ありがとうございます。
>>__USE_GNUの拡張ありカーネルでないとつかえない
って知りませんでした。
POLLHUP使ってみます。
39 :
デフォルトの名無しさん :2007/08/24(金) 04:13:20
AN HTTPの最新版が欲しくて中田昭雄氏のサイト行ってみたけど見れない… 誰か最新版の投下お願いします…
vectorにあるぜ
vectorにあるのは古いverですね。(1.37b) 最新は中田氏サイトのgoogleキャッシュ見る限りだと1.42pみたいです。
45 :
デフォルトの名無しさん :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()
ルータの内側から、ルータの外側用アドレスでアクセスしてみたってこと?
っwireshark あとルータのログも見とけ
48 :
45 :2007/08/27(月) 00:50:11
中から来たパケットを逆納豆テーブル見て 折り返してくれるかどうかはルータによる。
ネバツイテ 折り返そうしても出てこないことあるよなぁ
あるある
52 :
デフォルトの名無しさん :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.レスポンスを受信したら切断して終了
53 :
52 :2007/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で待っているのですが、
ここで適当なタイムアウトを設定して、アプリ終了フラグを見るとか・・・?
1.発生する 2.というか、WSAEWOULDBLOCKが帰ってくるまで recvをループで回すほうがいい 3.FD_WRITEは、sendがWSAEWOULDBLOCKを返したときに、 送信を再開するために使う。つまり,1)recv直後にsend 2)WSAEWOULDBLOCKがかえってきたら3)FD_WRITEを待って、 ふたたびsend 4.同時に終了したいときにSetEventされるようはhEventをまつ
とにかくしね
>>54 recvをループさせるのはrecvが0を返すまででいいんじゃない?
57 :
52 :2007/08/31(金) 01:14:50
>>54 ありがとうございます。大変勉強になります。
4の回答が少しわかりづらいのですが・・・^^;
イベントオブジェクトをもう1つ用意して、WSASetEventでシグナルにするとか・・・?
>>56 ありがとうございます。
recvからは0が戻るか、WSAEWOULDBLOCKが発生したらrecvを呼ぶのを中断して
再度WSAWaitForMultipleEventsで待てばよいでしょうか?
現状はそうしていますが、これで良いのか判断つかなかったので・・・。
つーかさ、1ソケットで1スレッドを占有するなら 本来、ブロッキングソケットで足りるんだよ。 イベントなんか用意する必要も無く。 もちろん、鯖がsendでブロックしている間にもデータが送られてくるような 作り(プロトコル)なら話は変わってくるがね。 で、それで済むところをわざわざEventを使ってるのに 終了シグナルと両方待たなくてどうするのさ。
ごめん。
56だけど、recvが0を返すまでってのはブロッキングソケットの終了待ちロジックだ。
ノンブロッキングソケットの場合、受信データがなければエラーになって
WSAEWOULDBLOCKを示す。なので、0は基本的に返らないが、接続終了時には
0を返す場合がある。
なので、
>>57 のようにループして両方判定しておけばOK。
ブロッキングソケットの場合は、受信データがなければ受信データがくるまで
ブロックする。だから、ブロックしたくなくて、イベント処理をしているなら、
recvのループはまずくて、recv後は必ずFD_READを待たなければいけない。
60 :
デフォルトの名無しさん :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は問題ない環境です。
メンテしやすい方法
キューにたまるのを待って send なんてしなくても、キューにためず直接 send しちゃっていいんじゃないかと思うけど。 あと、select は扱えるソケットが 64 個までとか変な制限がある場合があるので、いちおう確認したほうがいいかもしんない。
select自体は、あらかじめFD_SETSIZEを128とかに 定義すれば、その制限からは外れるみたいな。
スレッドはソケットごとに2個づつ使うので、selectは1socketしか待たないのですよ なので、スレッドが大量にできるために、必要の無いスレッドはなるべく休止状態にしておきたいのです。 キューに入れるのは送信するのが10GBとかなのと、ヘッダをつけたりしているので、 send途中であふれた場合にどっかに取っておく必要があるのと、ある程度バッファに入れたら送信自体を停止する必要があるため。 スレッドを大量に作るのは定石とは違うのかも。
pollでひっぱれよ
FD_SETSIZEって変更できたっけ?
sendfileしてあとはシラネ、みたいな。
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 */
>>64 そんな設計なら普通にブロッキングモードにしとけば
send は送信バッファが一杯になったら空くまでブロックしてくれるし
recv は受信データが無ければ来るまでブロックしてくれる
select も独自キューも使う意味なし
>>69 スレッド・同期スレッドの場合には、sendはソケット内のバッファが開くまでブロックすることは期待しているけど、
送信するデータが無い場合にはブロックしようが無いので、送信データが来るまでビジーループにするわけにも行かないので、
キューを作ってそれが空じゃなくなるのをコンディションなどで待つ必要があると思うのですが。
受信側はそのとおりになってます。実際は受信データがきたら
ヘッダを解析してまとまりごとにデータを纏めて
メインスレッドにイベントを投げて受信したデータを処理しています。
現在4種類とも実装して、設定で切り替えられるようにしていましてどれも動いてはいるのです。
他にもWinsocksだと非同期IO(OverlapedIO/sendmsg)などで実装するなど色々サンプルはみているのですが
実際どれがいいのかは環境依存?
スレッドを大量に立てると高負荷になるし、
タイマーでポーリングすると、タイマー内で処理をする量の制限を掛けるため、
性能がいまいちな場合もあります。
ちなみに、現在のキューは2つの同期制御付きキューを使って、
片方を処理データに、もう片方を未使用のメモリ用に使ってます。
これで、送信データを設定する場合に未使用のメモリの部分に直接ファイルなどから読み込むことにより、
キューへのコピー処理も起きないようにしています。
受信データは未使用メモリのキューから取ってきて、使用中のキューにヘッダ+データが来た時点で入れて処理しています。
最初は同期ソケット+スレッドか、非同期ソケット+非スレッドの2種類になるのかと思ってたのですが、
実際は
>>60 に加えて受信、送信スレッドそれぞれスレッド無しかどうかも独立に扱えるようにはなっているのです。
でも、結局いろいろ作ってもどれでも変わらないのかも???
Windowsの場合、性能的にはIoCompletionPortを使うのがベストと聞いた。 IoCompletionPortは非同期ソケットをベースとするけど、 扱うソケットが増えてもイベントやスレッドの生成自体を少なくできる、らしい。
OVERLAPPEDを使うとSend/Recvで扱うバッファをユーザーが先に指定できるので データの送受信にコピーが要らない。(逆に言えばその辺の管理をこちらがやる) 更にIoCompletionPortでスレッドの管理をやらせると利用可能な最大スレッドも指定できる ・・・という認識だったけど。
73 :
デフォルトの名無しさん :2007/09/01(土) 16:32:00
ネットワークケーブルで繋がったパソコンを遠隔起動させるプログラムを作りたいのですが、 そのために必要なマジックパケットがどのようなものでどのように送信するのかが分かりません どなたかご存じないでしょうか? やりたいこと自体は単純で、マックアドレス指定したパソコンの電源を入れるだけです (フリーソフトのWakeUpみたいな感じです) ちなみに自分が開発に使用している言語は純粋なC言語です
75 :
デフォルトの名無しさん :2007/09/01(土) 17:20:21
ところで、 みなさんrecvの最大受け取りバイト数を1にしてループ回すのは極悪だと思ってますか? それともそれでもいいと思いますか。
世の中には実行効率なんかどうでもいい場面ってのがあるから、状況しだいでは別にいいんじゃね
それが極悪ならfgetcを繰り返すのも極悪になるぞ
>>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回叩く。この差は大きい。
> recvを1000回呼ぶのは、システムコールもきっちり1000回叩く。 実装依存だろ。頭固いな。
>>79 > それが極悪ならfgetcを繰り返すのも極悪になるぞ
実装依存だろうけど, unix 系では通常
fgetc はライブラリ: システムコールのオーバヘッド小
recv はシステムコール: システムコールのオーバヘッド大
なので recv で 1 バイト読み込みループは極悪
recvで1コールするとUnix系だと KernelとUserでメモリコピー毎回発生するぞ?
selectを抜けた後呼び出して 中ではバッファリングしてるんだけど 特定の条件をクリアするまでは 読んだことにならないread?表現難しいな のスケルトンが欲しい。
>>84 条件とかかけよぼけが
頃すぞぁぁぁあ?
一人で読み書きするならそもそも
条件なんて勝手に決めろよぼけ
ってはるだろうがーこの糞ピザ野郎が
お前は1000回氏ね
>>85 条件なんて案件ごとに違うじゃん
だからライブラリじゃなくてスケルトンって書いたんだってば
愛してるよ
超初歩的な問題ですみませんが、どうしても判らないので教えてください。 p2pのネットゲームを作っていまして、 サーバになる方は、ポートを空けて接続を待つのは判るんですが、 空けるポート番号は、1024〜65535の間でしょうか? それとも、動的/プライベートポートの49152〜65535の間でしょうか? 0〜1023は一般的なポート番号で使わないほうがいいのは判りますし、 1024〜49151は、予約済みポートですから、 ユーザーが自由に使えるということで、49152〜65535を空けるようにしましたが、 たとえは「ひぐらしデイブレイク」では37564など、予約済みポートの範囲内で、 ポートを開放している場合があります。 またクライアント側に割り当てられるポート番号は動的/プライベートポートから 選ばれるみたいで、すでに別のソフトでクライアントとして、そのポートが使われていて、 いざp2pゲームでサーバとして、ポートを開放しようとしたら、空かないことがあるかも知れないですよね。 変な文章ですみませんが、ポートを開く約束事について、良くわかりませんので、 どうか教えてください。
>>87 0-1023は使わないほうが良いだろうけど、それ以降のポートが全て決められている
わけでは無いし、星の数ほど存在するソフトが65535のポートで足りると思うか?
思いついたポート番号をググって使われてなさそうなら、使ってしまえ。
と適当な事を言ってみる。
使おうとしたポートをbindさせた時点で既に他のソフトで使われているようなら
エラー出るし、問題無いだろ。
90 :
87 :2007/09/07(金) 20:45:21
早速の返答ありがとうございます。
説明不足でしたが、
>>89 さんの言うような、ポート番号を入力できるメッセージボックスがあり、
ユーザーが開けたいポート番号を自由に決めれるようになっています。
ただ、そのポート番号を選択できる範囲が、1024〜65535の方がいいのか、
49152〜65535の方がいいのか、わかんないのです。恥ずかしい話・・・
普通、自由に使えるプライベートポートというなら、みんな49152〜65535の範囲でポート開放するのに、
先の「ひぐらしデイブレイク」では37564の予約済みポートの範囲内でポートを開けるし、
あるp2pソフトの使用説明サイトでは、1024〜65535までの間で好きな数を選べると書かれています。
動的/プライベートポートがあるのに、わざわざかち合う可能性のある予約済みポートの範囲を使うのは、
ルーターを使用している環境での、ポート開放に有利になるんじゃないかと、勘ぐってしまいます。
ちなみに、私のネット環境はbフレッツで、回線終端装置から直にLAMケーブルでパソコンにつながっているので、
ルーターのポート開放をしたことが無く、ルーターについてよくわかりません。
あんまり、ポート番号について、気にする必要は無いのでしょうか?
もちろん気にした方がいい。 有名どころのポートや、 過去に問題があってセキュリティで睨まれているポートは避ける。
攻撃力高そうなケーブルだなLamケーブル
93 :
87 :2007/09/08(土) 00:20:45
返答ありがとうございます。
>>92 さん、すみません。LANケーブルでした。
あと、
>>91 の書き込みで、
「有名どころのポートや、
過去に問題があってセキュリティで睨まれているポートは避ける。」
と、あるので、自由に使える動的/プライベートポートである49152〜65535の間で、
ユーザーに解放させるポート番号を選択させた方がよろしいでしょうか?
そうなると、なぜ他のP2P通信のゲームやソフトは、予約済みポートの範囲内で、
ポートを開放しているのかがわかりません。自分が見たところ、動的/プライベートポートで
開放しているところより、予約済みポートの範囲で開放しているところが多い気がします。
問題のwinnyも、初期は7747をあけていましたし・・・。
このスレッドの皆さんには常識なのに、こんなことをしつこく聞いて申し訳ないと思いますが、
ユーザーに開放させるポートの選択範囲は、
1024〜65535の方がよろしいのか?
49152〜65535の方がよろしいのか?
どうか教えてください。
本当にすみません。
>ただ、そのポート番号を選択できる範囲が、1024〜65535の方がいいのか、 >49152〜65535の方がいいのか、わかんないのです。 個人的には、そういう妙な縛りはイヤだ。 1〜65535を自由に選択できればいいと思う。 そのダイアログが毎回表示されて、ユーザにポートを選ばせるんなら、ちょっと鬱陶しいかもしんない。 適切なデフォルト値を用意しておいて、一般ユーザはそれに触らずに済むようにして、 わざわざ変更したいと思うパワーユーザだけ、設定画面を出して変えればいいと思う。 そういう人は、自分が何やってるか解ってるだろうから、任せとけばいいよ。
>>93 多くのアプリが1024〜49151ってのは、49152〜65535にすると、本当に動的に取得してる
アプリやクライアントなどと競合する可能性があるからたまたまタイミングによってサービス
が起動できない可能性を嫌っているんじゃないだろうか。
1024〜49151なら、少なくともマシン/OS設定のチェックをキチンと行えば、実行時のエラー
は最小化できるし、それがたとえ定義済みのポートだったとしても、サービスの運営側と
すれば、自分のマシンに競合アプリが入ってなければ実質的な問題は発生しないので
気にしなくて良い。
もっとも動的といっても、例えばクライアントの使用するポート番号(エフェメラル・ポート)
はOSによって違い、FreeBSDなどは確かに49152〜65535だが、Windowsの場合、
1024-5000が使用されてるみたいなので、厳密な意味での競合回避できるかは分からないし、
心理的なものかもしれないが。
でも、そのような理由で例えばデフォルトは5001〜49151の範囲から定義済みでないものを
選ぶみたいな考えもあるかもしれない。
というわけで、ポートの選択は実際にサーバを立てる人の好みの問題や、
場合によってはファイアフォールなんかとの兼ね合いもあるので、一般にきつくするのは好まれない。
ただ初心者が使う前提のアプリなら推奨値の範囲で縛りを入れておいた
方が後々のトラブル回避点でメリットはあるので、あとはアプリしだいでは。
apacheを使わないWebDAVサーバって有ります?
動的portとプライベートportが、49152〜65535ってのは決まりごとです。
>>95 は甚だしく不当な言明。無知蒙昧。
> 少なくともマシン/OS設定のチェックをキチンと行えば、実行時のエラーは最小化できるし、
に至っては言葉を失う。
99 :
95 :2007/09/08(土) 18:26:23
>>97 申し訳ない。
以前サーバ開発のプロジェクトにいたとき、周りがみんな
この程度の認識だったので、正直甘く考えていた。
これからは気をつける、もうそんな開発の機会もなさそうだけど。
100 :
87 :2007/09/08(土) 22:47:55
皆さん、ありがとうございます。これらの書き込みを、いろいろ参考にさせてもらいます。 最終的にポート番号の入力ですが、入力ボックスを用意しますが、 ゲームクライアントが最初にログイン画面を立ち上げた際、49152〜65535の間をランダムに、 番号を割り振るようにします。 そこで、IDネーム、パスワード、ポート番号を決定したら、それをログインデータとしてセーブし、 以後、ソフトが立ち上がるたびに、ログイン画面の入力ボックスには、ID、パスワード、ポート番号が、 すでに入力されているようにします。もちろん、この時点で入力ボックスの中身を変更して、ログインしたら、 ログインデータも新しい方に修正されます。 ランダムにポート番号を割り振る時は、49152〜65535の動的/プライベートポートの範囲ですが、 入力できる範囲は、予約済みポートを含めた、1024〜65535の範囲を選択出来るようにします。 こんなもんでどうでしょうか?
acceptする方のportは範囲を狭めておかないと、 firewallの設定を全部開けておく必要があることになる。
そしてUPnP
自分のパソコンにメールサーバを入れてそれを使ってメーラーのテストはできますか? 何か無償で取れるサーバーがあればいいのですが・・・
>>103 UPnP対応ルータとかの普及率ってどっかに統計ないかな?
それは知りたいな でもUPnP対応とか言ってても酷い実装もあるから当てにならなかったりするんだよな
pollで3つのfdを管理するさんぷる どっか墜ちてませんかね? selectが使えない組込みデバイスなので ちと困ってますw
>>108 24時間やる。こなたの得ろ画像を500枚用意しろ。
そいつと引き換えにオレがサンプルを渡してやる。
111 :
デフォルトの名無しさん :2007/09/13(木) 06:52:35
Windowsソケットで struct sockaddr_inの最後のメンバにsin_zeroが有ります。 このメンバの値は何に使われるのですか?
パディング
113 :
デフォルトの名無しさん :2007/09/13(木) 07:30:17
そうだけど、値は全く参照されない仕様なのかな?
はい。
115 :
デフォルトの名無しさん :2007/09/13(木) 08:35:09
>>114 肝心な所は知らないんだな。お前は役立たずだ。
このスレを見ている人はこんなスレも見ています。(ver 0.20)
会社で使えない奴、それはワタシ/アイツ [プログラマー]
>>111 Windowsはどうなのか知らないが、アドレスをソケットにバインドする際、アドレス構造体を
各インタフェースの関連アドレスとバイナリ比較する実装があるらしい(sin_zeroが0であることを
前提としている)。
プロトコルスタックの内部処理で何か使われているかもしれないし、sockaddr_in全体を最初に0で
初期化して使えば問題ないんじゃないのかなあ。
まあ、
>>115 の言っている「肝心な所」が何なのか、ちょっと気になるけどね。
俺も役立たずかもしれないな〜。つーか、教えてくれたって良いじゃない。
117 :
デフォルトの名無しさん :2007/09/13(木) 10:42:18
やっぱりそうですね。 そんなわけで0にしようと思いましたが失敗しています。 8バイトほど0を入れたいのですが実行時エラーです。 大文字なのが原因かもしれません。 SOCKADDR_IN sa; memcpy(sa.sin_zero, 0, sizeof(sa.sin_zero));
119 :
デフォルトの名無しさん :2007/09/13(木) 11:22:54
FARとか付いたりしてるからmemcopy()が使えないってことかな?
memcpyがどういう関数か調べろよー ってか、forループで書けば上手くいくはずだから、 memcpyを使うこと自体が間違いって気づきそうなものだけどな
memsetだろうなw
>>116 みたいな懸念があるなら、
(そういうのは狂っていると思うが)
sockaddr_in全体を0 fillしとかないと駄目だろ。
memsetだ。オマイラえらいなー。
124 :
デフォルトの名無しさん :2007/09/13(木) 12:05:37
socketを作る時のtype指定に使うのがPF_*。 sockaddrはAF_*の方。
>>125 でもさ、「なんかもうそのへんどうでもいいよ」って
socket関連のAPIの仕様書に書いてあるんだよね
どうでもいいってことはAとPを間違って書いても値が同じになるような 値が定義されているってことかな?
>>127 間違えそうなところはちゃんと同じ値になってる。
それならよし
オンラインの格闘ゲームを作りたいのですが、ローカルで通信のテストを してみたところ、1秒間に40バイトのデータを17回程度しか やりとりが出来ません。 pingだと1ms程度でるので、もっと通信の頻度が高くても良いと思うの ですが、大体こんな程度なのでしょうか? 通信にはDirectPlayを使っています。転送処理の行はこんな感じです。 (WinSockだと早くなったりするのでしょうか?) HRESULT hr = Get_DPlay()->SendTo( this->dpnid, &dpnbuffer, 1, 60000,//タイムアウトまでの時間 NULL,NULL,DPNSEND_SYNC );
nagleかな
なんとか解決できたみたいです。 作成したスレッドにてSendTo関数を実行していたのですが、スレッドの 優先度をあげてみたところ、1秒間に240回程度の速度が出るように なりました。 アドバイスありがとうございました。
TCPだと、sendしてもすぐには送信されずに まとめて送れるモノが無いかどうか少し待つ 実装が多いよね。優先度低いと町が長くなる
bsdのzero_copyって なんでlinuxにないの? つーかこれじゃ何もできねーよw
> 何もできねー ほう
RDMA
RDMAなんていらねーよw マシン2台間での関係でそんなでかい もん使うなんてあほだ zero_copyあればいいのに Linuxは糞だな
条件小出し方式ですな
はいはい。愚痴はいいからさっさと作れよ 納期過ぎてんだから。
boostにネットワークライブラリってありますか?
なぁなぁ頼むよ zero-copyする方法教えてくれよ
>>140 1.35よりboost::asioというのが使えるようになったらしいです。
お前ら粘着するぞゴラ アボーンできねぇから迷惑きわまりねぇぞ 速く教えろよコラ
>>142 ありがとうございます
早速試してみます
>>143 こういうノリ久々にみた。個人的に好き。
やっぱり2chはおまいみたいなのがいないとつまらんよね、まぢで。
なにをするために、zerocopyにしたいの?
いなくなっちゃったね。 zerocopyくん。
以下コピペ
現在、Windowsソケットプログラム(winsock1.1)により、P2Pでの非同期のTCP通信プログラムを組んでます。
そこで、クライアントからサーバーへの同時接続のチェックをするために以下のような処理を行っています。
#関係ありそうな情報のみ載せます。足りなければご質問下さい。
OSはWindowsXP HomeEditionです。
なお、OSによる同時接続制限はBiotというツールにより20000というふうに設定しております。
・クライアント
1.ソケット3000個用意
2.for文ループ処理によりソケット数分Connectを実行
・サーバー
1.listenの同時接続最大数は20000に設定
毎回Connect実行時、大体2000回目辺りからエラーが出てきます。
その後、イベントが返って来た時のエラーチェックでも、WSAECONNREFUSED(10061)で「サーバーにより接続が拒否された。」というエラーが検出されます。
結局、接続成功は500〜700回ぐらいでした。
この現象に対する対処法や解決法はないでしょうか?
現状では、全てのConnect要求を成功できるようにしたいと思っております。
子プロセスを作成するような方法は時間が無いので考えておりません。
9/18にも同じようなしておりますが、前より詳細を書いて再投稿いたしました。
以上、よろしくお願い致します。
ttp://oshiete1.goo.ne.jp/qa3364947.html こんな状態です。どなたかわかる方はいませんでしょうか?
サーバ側の accept を回す処理が追いつかなくてバックログがあふれたとか? listen をいくら大きくしても、あれただのヒントだった気がするが・・・
152 :
150 :2007/09/22(土) 20:15:40
>>151 って事は、いくらOSのほうを対応しても、listenではじかれてしまうんですか。
SOMAXCONNを指定すれば対応できたりしますかね?
そのくらい、すぐ試してみれば? あとは、余計な処理を一切省いたacceptだけのループでなら接続できるのかどうかを実験してみるとか・・・例えば while(true){ accept(fd); } みたいな。 あるいは、accept するスレッドを複数立ち上げてみるとか。 それで無理なら無理っぽいな。 OS 変更も検討してみるべきかもね。
154 :
150 :2007/09/22(土) 21:24:40
155 :
150 :2007/09/22(土) 22:30:36
>>153 SOMAXCONNを指定したら、逆に成功確率はかなり減りました。170回くらいでした。
ところで、サーバーの動作は非同期通信なので、ループ処理は無理でした。
あと、スレッドは立て方がわかりませんのでなんとも・・・。
forkはUNIXだし、その前に使えないし・・・。
無知ですみません;
非同期なら、accept完了がわかった時点ですぐ閉じてみたら? スレッドは、beginthreadex。
非同期って WSAAsyncSelect のやつかな シングルスレッドサーバだと他のソケットを read したり write したり データを処理したり色々構ってやってる間は当然 accept を呼べないから、 処理に時間がかかってるようなら、やっぱりその間に接続要求がたまりすぎて溢れるんじゃないかと
Winsock1.1+WSAAsyncSelectでハイパフォーマンスなサーバを書こうとするのも アレだが XP Home Editionというのも終わってるだろ。 何が悲しくてクライアント用のOSで1000のオーダーの同時接続数をさばかにゃ ならんのだ。 せめて2003サーバに汁。 ハードもそれなりにおごれや。 で、使うべきはIOCPな。 WSAAccept()をポストし続けるスレッドも専用で回せ。
159 :
150 :2007/09/25(火) 02:08:20
>>156 とりあえず、やってみます。beginthreadexは調べておきます。
>>157 その線が一番怪しいんですが、TCP接続制限をBIOTで20000に設定して、
listenも20000にしているんで、溢れるという事が無いように思えるんですが・・・。
listenのバックログの最大数があるらしいんですが、まだ調べきれてなくて
わからない状態です。
>>158 サーバーはまぁ、色々と事情が…;
でも、論理的にはTCP接続制限をはずしているんで、そこでacceptが失敗するのは
OS以外のことだと思うんです。
私が知らないだけかもしれませんが、XPと2003サーバってサーバーマシンとして
使用した際に何か違いってあるんでしょうか?
>>159 そう思うなら、Linux入れて同じハードでほぼ等価の
コード作ってためせ
たぶんおきねーからw
>>159 XP Homeで3000ソケット接続を試してみたけど、特に問題なく接続できたよ。
1,環境が良く分からない。サーバーはマルチプロセッサマシンなの?
2,クライアントでconnetを行うときにSleep関数を入れてconnectの接続間隔を長くしてみては?
>>159 最小限のソース晒してくれ
時間の無駄だ
163 :
デフォルトの名無しさん :2007/09/26(水) 09:14:56
無線LANに接続しているPCの数を取得するにはどうすればよいのでしょう?
>>150 acceptの処理時間とか無関係。
サーバのOSでTIME_WAITでポートが枯渇してるだけ。
TIME_WAITについて深くしりたけりゃぐぐれ。
めんどくさけりゃSO_REUSEADDR。
>>163 a. 無線LANのWebからステータスを得る
b. SNMP,MIBでぐぐーる
サーバ側のポートが枯渇するの? サーバ側のポートはずっと同じで、クライアント側のポートが変わるだけじゃ?
ちゃんとした通信手順を踏めば即座にポートを解放してくれる 行儀の悪い通信をすると TIME_OUT まで待ってから解放される TCP/IP の仕様だから Linux でも Windows でも同じコードなら やっぱり通信数に制限が出るような気がする
>>164 > ポートが枯渇してるだけ。
馬鹿丸出し。
SO_REUSEADDRは再びbindするときの話だっけ。
>>150 とは関係なさそうだな。
170 :
デフォルトの名無しさん :2007/09/26(水) 13:16:22
acceptを終了するにはどうしたらいいの? acceptで待機中の時に別スレッドからsocketcloseを呼び出したら WSAEINTR (10004) ? 意味 : 関数呼び出しに割り込みがありました。 ? 説明 : ブロック操作は WSACancelBlockingCall (Wsapiref_704y.asp) の呼び出しによって中断されました。 が呼ばれるんだけど、acceptの終了方法はこれであってるの? winsocket2.2
172 :
デフォルトの名無しさん :2007/09/26(水) 14:01:34
ということはconnect内部のbindで失敗するとWSAECONNREFUSEDが返ってきちゃうのか。 原因に気づき辛そうで厄介だなあ。
>>173 クライアント側でユーザーポートが枯渇するとWSAENOBUFS (10055)が返ってくるんだけど。
おまえら, なんかトラブったときに TCP のステートダイアグラム 見ないでプログラム修正とかしてるのか?
177 :
150 :2007/09/27(木) 10:53:38
一向に解決しなかったけど、今の状態で妥協する形になりました。
助言くれたかたサンクスです。
>>176 TCP のステートダイアグラム
とは?
181 :
デフォルトの名無しさん :2007/09/30(日) 07:42:09
複数あるNICのインタフェース(またはローカルIPアドレス)を指定してソケットを オープンしたいのですが、方法はありますか? Windows XP SP2
bind
183 :
デフォルトの名無しさん :2007/09/30(日) 10:03:51
すいませんclient側の話なんです。 bindってサーバ側ですよね。 NICが2枚刺さってるPCがありまして、片方のNIC(あるいはIPアドレス) を指定して通信させたいのです。
184 :
デフォルトの名無しさん :2007/09/30(日) 10:07:03
特定のNICのIPアドレスを使ってconnectしたいという事ですね。
>NICが2枚刺さってるPCがありまして、片方のNIC(あるいはIPアドレス) >を指定して通信させたいのです。 それもbindでできたと思うけど。ローカルホスト側のsocket endpointを明示的に指定する処理は 全部bind。
初学者は誰だって勘違いすることがある。 めげずにがんばれ。
才能内から真だ ほうがいいと思うけどね こんなのもしマジでプロジェクトに 混じってたらすげーこえーしw
bindできました!
ム板でプロジェクトうんぬん云ってるDQNはマ板に逝け
194 :
デフォルトの名無しさん :2007/10/01(月) 23:26:27
質問があるのですが、友達の家から私の家まで通信実験を行いたいと思っています。 家はADSLでプライベートIPではなく、グローバルIPを得たいのですが、方法が分かりません。 どういった方法があるのでしょうか。質問よろしくお願いします。
お使いのプロバイダに訊け
使ってるプロバイダとかあなたの家や友達の家のネットワーク構成によるけれど、 自宅までグローバルIPが割り当てられてる可能性は高いと思う 家がプライベートIP云々言ってるが、家じゃなくて 「自分のPCが」 の間違いだろう たぶんルータを挟んでるんじゃないかね ルータにはグローバルIPが割り当てられてるかもしれんよ ルータの設定画面かなんかで確認してみ
>>194 実験ならば どこかのCGIを読むようにするのが一番楽だよ
ちなみにどんな実験? 速度の検証とか?
接続確認のテストならばテストになってないが??
ちょいと教えて 接続するクライアントソケットは データーの種類によって分けた方が良い? たとえば データーと制御データーがあった場合 1) ポートも分ける 2) ポートは同一だけどソケットを別にする (受信・送信バッファを個別に取られる事を期待) 3) ポートもソケットも同一で2つのデーターをプロトコルで分ける (ソケット別にしても内部的には同じ信号で扱われるから 1,2は 効果なし)
201 :
デフォルトの名無しさん :2007/10/02(火) 00:51:31
あと関連して もう1つごめん 2つのデーターは A,Bの2つのデーターが有った場合 1)大きなデーターAをそのまま送ると Bのデーターは Aが処理されるので MTUを参考に分割してBのデーターを 混ぜて送る 2)極端な例で無い限りオーバーヘッドが大きくなるので 気にしない これはケースバイケースですが考え方としては?
ごめん タイプミス 1)大きなデーターAをそのまま送ると Bのデーターは Aが処理されるので MTUを参考に分割してBのデーターを 混ぜて送る ↓ 1)・・ Bのデーターは Aが処理されるまで待たされるので・・
理学部ktkr まず目的を書け。 それと質問を推敲しろ。
204 :
200 :2007/10/02(火) 01:15:38
ごめん分りにくかったね 通信の効率化をしたいわけなんだけど 早い話 内容の違うデーターを そのまま送受信するか ある程度切って送るかです たしか内部的には以下の処理を行っているはずですので なにも考えずに送っても ある程度は効率化しているはずですが みなさんはどうしてます? ■小さいデーターは優先されて送信する(ルーター依存?) ■送信データーはMTU値に切断され送信される
実際に効率上の問題に直面してから考えればいいと思われ
>>204 > ■小さいデーターは優先されて送信する(ルーター依存?)
どこの星の話ですか?
まずはタイミングの門をくぐって セキュリティ地獄に逝くのじゃ。
>>204 0x20以上で構成してSTXとETXではさむ。
209 :
200 :2007/10/02(火) 01:36:26
>>205 まあ実際はそうなんだけど・・・・
正直 通信よりもアプリの見直しの方が効果あるだろうし
ちょっと例を書いてみます
データーA
WM_MOUSEMOVEからのデーターを送信する
8Byte程度のデーターを1秒間に100個ほど送る
(内部的に遅延されるので実際は2K程度)
リアルタイム性重視
データーB
1秒間に1度画面をキャプチャーして送る
1027 X 768 X 3バイト
この場合はどうする?
当然 差分を送るとか根本的な事は無しで
1)Socketを分ける・分けない ← 私的には意味無いと思ってる
2)データーをMTU毎(または適当なサイズ)に切って
A,Bを混ぜて送信
210 :
200 :2007/10/02(火) 01:39:03
>>206 どこかで読んだ事あるんだけど
どこの星の話かは忘れた
Yahoo,OCNとかだと IPフォンのパケットは優先されてる
らしいから それと勘違いかな?
>>209 なぜかTCP前提で考えてるようだけど、そんなに効率気にするならUDPの方がいいんじゃない
そういった多少のデータロスが許容されるリアルタイムデータにTCPは効率悪い
ところで、それなんてスパイウェア?
新手のwinny用黴菌つくってんのかも
劣化VNC
216 :
200 :2007/10/02(火) 12:02:31
>>213 だからあくまでも例だって・・・・
そもそも通信効率以前の問題だし
劣化 VNC画面・マウスの送る方向違うし
>>212 にあるような仕組みを自前で実装してるのか
聞きたかった
>>216 やりたいことは2つのストリームをシリアルな通信経路に多重化することだろ。
後は、多重化を自前でやるかTCP/IPスタックにやらせるか。
>1)Socketを分ける・分けない ← 私的には意味無いと思ってる
意味無くない。
>2)データーをMTU毎(または適当なサイズ)に切って
> A,Bを混ぜて送信
この程度でMTUなんか無関係。
小賢しいこと考える前に手を動かせ。
他人の知識を借りたいのなら、自分が無知であることを認識しろ。謙虚になれ。
VNCやRDPを調べればいい。
>>216 簡単に高速かする方法あるよ?
FPGAで作ればいいんだよw
鯖よりボードの方が高いw
> (内部的に遅延されるので実際は2K程度) よくわからんけど Nagle を止めれば済む話?
その手の通信ってトンネリンングさせるかも知らんし、 生パケットがどう飛ぶかなんて議論は意味ない気がする。 画面データはアイドル状態待ってから飛ばせばいいし、 移動系メッセージなら100命令飛ばすんじゃなくて 1命令にまとめる事でも考えた方が。 pcAnywhereは反応重かったな。
224 :
デフォルトの名無しさん :2007/10/03(水) 19:44:50
ネットワークプログラミング初学者です。 サーバーサイドプログラムとクライアントサイドプログラムのふたつを作成した場合、 通信実験のデバッグを簡単に行える方法ないですか? 今、サーバプログラムをメインPCに。クライアントプログラムをUSBメモリに移してノートPCへ。 といった面倒なデバッグ方法です。>< よろしくお願いします。
両方ともメインPCで動かす
VMware/VirtualPC/Paralles/VirtualBoxで仮想PCを用意する。
ネットワーク上繋がってるPCなのにUSBメモリでコピーって意味わからん
ネットワークの共有も知らんでネットワークプログラミングとか大丈夫?
C#.NETでストリーミングデータの受信のプログラムを 作成しているのですが、Socket.Selectが思った通りに動作していません… ストリーミングのデータ形式は ヘッダ2バイト サイズ2バイト 以下データ このような形式なのですが、受信をしていくうちに、サーバー側の 送信に追いついてしまい、サイズ2バイトで指定されたデータが 読めない状態になってます Socket.Select( SocketList. null, null, 100 ); でリードできることは確認しているのですが、 sock.Receiveでデータの部分が数バイトしか読めない状態です ソケットはブロッキングで別スレッドで読み込みをしています PerlやWinsockのSelectとは動作が違うのでしょうか? 基本的な質問で申し訳ないですが、よろしくお願いします
>>229 selectはあくまで「データがあるかどうか」を調べるだけ。
何バイトあるかなんて知らん。
・データがあれば読み込んでローカルのバッファに溜める
・バッファにデータひとかたまり(ヘッダ+長さ+データ)があれば処理開始
を独立に行えばいい。
複数データが一度にreadできてしまうこともちゃんと考えとけよ。
>>229 ストリームソケットは区切りのないただのバイト列なので、例えば100バイトを3回送信しても、1バイトずつ300回受信するかもしれないし、300バイトを1回受信するだけかもしれない。
そういう前提で扱う必要がある。
100バイトずつ処理したければ、100バイト溜まるまで繰り返しrecvを呼ぶ。
233 :
デフォルトの名無しさん :2007/10/04(木) 23:26:47
すれ違いかもしれませんがネットワークに詳しい皆さんに質問を、、、
TELNETを使用しHTTPの勉強をしております
Yahooファイナンスから企業の情報を集めたいと思っています。
http://charge.quote.yahoo.co.jp/q?s=1301&d=t の情報を見たいとき
telnet charge.quote.yahoo.co.jp 80
Trying 124.83.147.185...
Connected to charge.quote.yahoo.co.jp.
Escape character is '^]'.
GET /q?s=1301&d=t
The document has moved <A HREF="
http://quote.yahoo.co.jp/q?s=1301&d=t ">here</A>.<P>
<P>Additionally, a 302 Found
error was encountered while trying to use an ErrorDocument to handle the request.
となってしまい情報を見ることができないでいます
302なので/q?s=1301&d=t ←ここではないほかのURLに情報がありそうなのですが
http://charge.quote.yahoo.co.jp/q?s=1301&d=t の中の情報が書かれているのか真のURLがどこなのか判断する方法があったら教えていただけないでしょうか
>>234 ありがとうございます
恥ずかしい、、、、、申し訳ないです
てゆーかさ、GETをHTTP/0.9でやってるから レスポンスヘッダが付かなくて 302なレスポンスであってもLocation等で判断できないんだけど わかってるのかね。
FORMのPOSTをGETでアクセスできない事があるんですが?
そうですか。
240 :
デフォルトの名無しさん :2007/10/07(日) 00:22:02
ノンブロックなソケットディスクリプタでサーバにコネクトするときに そのコネクトがコンプリートしたかのステータスをゲットしたい。 ミーは何をドゥーすればいいの?
241 :
240 :2007/10/07(日) 00:23:57
ミーがユーズしてるOSはLinuxです
たしかselectで書き込み可能が帰ってきたらコネクト完了
243 :
240 :2007/10/07(日) 00:27:21
>>242 ハリーなアンサー サンキューです。
バット、ノンブロックなソケットだとオルレディでキャンライトみたいです。
ワンモアトライしてみます。
getpeername(2)がENOTCONを返さなくなった時がcomplete
write(send)でFD_WRITEを指定してselect(WSAEventSelect)待ちするケースって 非同期モードですか? 環境はWindows 2000 XPです。
というか、FD_WRITEを指定してselectってどういう時に使うのかわかりません。 「ソケットの送信バッファに空きができたことを通知」とのことですが、 一度もwrite(send)せず、いきなりselectしても検出してくれるのでしょうか。
>>246 接続確立時に一回だけFD_WRITEの通知がきた気がする
その後は、バッファに空きのない状態→空きのできた状態、になったとき、
つまりsendしてWSAEWOULDBLOCKが返ったあとにバッファに空きができたら通知される。
納得いきました。 ありがとうございます。
lingerがよくわからないんだけど 今の理解は ・最後に送信する側(closesocketを呼び出す前にsendを呼び出す側)の送信が正常に行われたかを判断するために使用すると思ってます。 そこで質問は ・最後に受信する側(closesocketを呼び出す前にrecvを呼び出す側)はlingerの必要はない? ・closesocketでlingerのタイムアウトエラーが返ってきた時は、最後の送信が正常に完了していないと判断し、エラーとするまたはリトライする と言うのであってるんですかね?
タイムアウトが起きると送信放棄。shutdownのabortが起きる。 その他はまあそういうこと。 MSDN Network Protocols Windows Sockets 2 About Winsock Winsock Programming Considerations Graceful Shutdown, Linger Options, and Socket Closure
251 :
デフォルトの名無しさん :2007/10/12(金) 16:12:26
日本信号の改札機はなぜ起動しなかったのでしょうか?
スレ違いだったらすみません。 DirectShowで動画再生するソフトを作ったんですけど 現在は再生する動画はローカルにある動画のみなので これをストリーミングに対応させたいと思っています。 ストリーミングについてRTPなどのプロトコルも調べたんですが Winsockを用いての実装手順がいまいち分かりません。 RTPのパケットを自分で実装して、データを入れる領域に 動画のフレーム、音声データを入れる形でしょうか。 動画ファイル自体をバイナリデータとして送り、ファイル出力された 動画ファイルを再生することなら出来るんですけど、ストリーミング の実装は実際にはどのような手順で行えばよいでしょうか。
動画ファイルの種類に寄る。 動画を映像と音声に分離して、さらにそれを一定量に分割出来なければ、難しいと思う。 AVIファイルをストリーミングさせるってのはナシな。
>>252 ファイル出力が完了しなくても再生をはじめれば?
YahooファイナンスってKeep-Alive使えないんですかね 毎回接続し直すの面倒なんですけど…
ぇ
257 :
デフォルトの名無しさん :2007/10/19(金) 09:02:36
TCPで非同期(WSAAsyncSelect)を使ってプログラミングをしています。 非同期において送信する場合どのように設計すればいいのかイマイチわかりません。 やりたいことは、接続要求があったらacceptしてファイルを送信するといった内容です。 ファイルの送信要求メッセージを受信 ファイルをバイナリモードでオープン 4096バイトずつ読み込んでsend() ファイルをクローズ ファイルを送信した後も継続して通信は行います。 sendもノンブロッキングになってるため、 while(ファイル読み込みが終わるまで){ send() } だと上手くいかないのかなと思います。調べてみると非ブロッキングにおいて連続してsend()を行おうとすると WOULDBLOCKという現象が起こって送信できない事があるとの事です。 FD_WRITEのメッセージも別に自分が送信したいタイミングで来るわけでもないのでイマイチ有効な活用方法がわかりません。 どなたかご教授願いますm(_ _)m
>>257 WOULDBLOCKならあとで続きを送信する
259 :
デフォルトの名無しさん :2007/10/20(土) 00:07:00
>>257 sendも非同期ですべてやればOK。
自分が、acceptまちなのかsendまちなのか。sendまちであれば、現在
何バイト送ったのか全部管理しる。
260 :
デフォルトの名無しさん :2007/10/20(土) 00:09:54
261 :
デフォルトの名無しさん :2007/10/20(土) 04:31:18
>>258-259 えっと、同期ならこんな感じの送信です。
while( read_byte = fread(sendbuf, sizeof(char), MAX_BUFSIZE, fp) ){
send(sock, sendbuf, read_byte, 0);
memset(sendbuf, NULL, sizeof(sendbuf));
}
WOULDBLOCKなら後で続きを送信するというのはこういう事でしょうか?
while( read_byte = fread(sendbuf, sizeof(char), MAX_BUFSIZE, fp) ){
if( send(sock, sendbuf, read_byte, 0)==SOCKET_ERROR ){
while( WSAGetLastError()==WOULDBLOCK ){
send(sock, sendbuf, read_byte, 0);
}
}
memset(sendbuf, NULL, sizeof(sendbuf));
}
あまり非同期っぽい書き方じゃないですが・・・。
>>259 さんのはちょっと理解が出来ないです。
send待ちとはどういう状況の事を言うのでしょうか?
UNIXネットワークプログラミング〈Vol.1〉ネットワークAPI:ソケットとXTI これは間違いなく良書だけど、はじめて学ぶ人にはお勧めできない Linux以外の他のUnixでの実装や、実装される過程(歴史)まで乗っていて 総じて詳しすぎる。もちろん分厚い。初心者はどこが重要化取捨選択するのが 難しいので2冊目の本として考えておいた方がよいとおもいます 言語がCなら、TCP/IPソケットプログラミング オーム社(ISBN4-274-06519-7) がオススメ。これ一通り読んでサンプル実行してみれば基礎は十分に理解できる。 内容もわかりやすく、本も薄めなので挫折する心配も少ない。
>>261 同期非同期に関わらずsendの戻り値はチェックしよう(送信したバイト数)
非同期に関してはWOULDBLOCKが返ってきたら、FD_WRITEが来るまで待つ。
264 :
デフォルトの名無しさん :2007/10/20(土) 08:47:52
>>263 てことは、送信は別のスレッドで行って、FD_WRITEに関してはフラグで処理するといった感じになるんですか?
// 送信可能フラグをたてる
case FD_WRITE:
send_flag = TRUE;
return 0;
// ファイル送信スレッド
while( read_byte = fread(sendbuf, sizeof(char), MAX_BUFSIZE, fp) ){
send_flag = FALSE;
if( send(sock, sendbuf, read_byte, 0)==SOCKET_ERROR ){
while( WSAGetLastError()==WOULDBLOCK ){
while( send_flag == FALSE ) Sleep(100);
send(sock, sendbuf, read_byte, 0);
}
}
memset(sendbuf, NULL, sizeof(sendbuf));
}
こんな感じでいいのかな・・・?
>>264 それじゃ、下のwhileループ群が同期になってしまうよー
慣れないうちは送信用のキューを用意すると良いかも。
キューに追加するのは自分の好きなタイミングで行い、
実際のsendやFD_WRITEの処理部分と分ける。
>>265 も書いてる通り、適当なサンプル眺めれば見えてくるかもね。
e1000の改造について詳しいドキュメントちょうだい
>>265 ん〜書籍を買うのに金銭的余裕が・・・。
月曜日に学校の図書館に行ってWinsockの本がないかどうか見てきます。
>>266 色々と調べてはいるのですが、いまいちFD_WRITEの使い方が理解しにくいです。
FD_WRITEメッセージが来たら具体的にどういう処理をすればいいのでしょうか?
FD_WRITEメッセージは自分が送信したいタイミングで来るわけでもないんですよね。
キューを実装するということは、こういう感じで実装するということですかね・・・
while( fread(buf) ){
push(buf);
}
PostMessage(,,FD_WRITE,);
FD_WRITE:
if( キューにメッセージがあれば ){
sendbuf = pup();
send(sock, sendbuf, sizeof(sendbuf), 0);
}
return 0;
pushとかpopとかこれじゃスタックっぽいですね。 脳内でキューに変換してくださいm(_ _)m
>>268 FD_WRITEはWOULDBLOCKになってから初めてバッファに空きができたら送られるくるもの。
(自分でPostするものではない)
つまり、キューが空になるか、WOULDBLOCKが返ってくるまでsendを繰り返す。
キューへのpushは好きなようにすればい。
サンプルもネットに転がってるはずだから調べよう。
271 :
260 :2007/10/20(土) 10:15:22
>>262 情報ありがとうございました。探してみます
>>262 横からサンクス。図書館で適当に借りてきたらソレだったので頑張ってやってみっかな。
>>268 >FD_WRITEメッセージが来たら具体的にどういう処理をすればいいのでしょうか?
>FD_WRITEメッセージは自分が送信したいタイミングで来るわけでもないんですよね。
「自分の送信したいタイミングで送信する」 という考えを捨てて、「FD_WRITEが来たときに送信する」 ようにしる。
send で WOULDBLOCK が返ってきたら、残りのデータはその場で送信するのはいったん諦めて、どこか別の場所に覚えておく。
FD_WRITE が来たら、覚えておいたデータを改めて送信する。
そのときも、送りきれないと WOULDBLOCK が返ってくるので、再び FD_WRITE が来るまで残りのデータをどこかに覚えておく。
ファイルを読み込んで送るだけなら、データを丸ごと覚えなくてもファイルの現在位置を覚えるだけで充分かもしれないが。
あと、send は渡したデータをすべて送信できる保証はない。
例えば send(sock, buf, 100, 0) とやっても、1バイトしか送信できない場合もある。
何バイト送信できたか戻り値が返ってくるので、送れなかった残りのデータはもう一度送り直す必要がある。
なぜそんなに面倒なんですか バカみたいですね
なぜって、非同期だからさ バカみたいだろ? おとなしく同期ソケット使っとけ
>>274 イベントドリブン式/非同期プログラミングの方法はどれも似たり寄ったりだぞ。
キーワードは「継続」だ。
まあ、この程度なら別にコルーチンを使うまでもないがな。
サーバ終了させるのってlistenしてるソケットを閉じればいいんだよね? それとも終了する関数があるの?
278 :
デフォルトの名無しさん :2007/10/20(土) 18:08:48
すいません。 初心者のくだらない質問を受けてください。 javascriptをHTMLの中に記述して様々なことができるのは、何となく わかりましたが、第三者に見られてはいけないプログラムはどうやって行って いるのでしょうか? つまり表示画面からソースを選択すれば、ソースが見れてjavascriptが 定義されていて、命令されているのはわかりますが、googleで例えると 肝心要の検索プログラムなんかは、絶対にソースなんか秘密で自社サーバー の厳重な管理の中で動いているわけですよね? それが見れないのは当然でわかっているのですが、HTMLのソースに記述 するjavascriptやphpなどから外部プログラムへのリンク命令?みたいな部分は 記述しないのでしょうか? またgoogleの検索プログラムもやはりjavaやphpなんですか? それともC言語系とかなんでしょうか? 何が言いたいのか自分でもわからなくなりましたが、どなたか教えて ください。
>>278 PHPのプログラムはサーバ側で動くのでブラウザからは見れない
JavaScriptのプログラムはクライアント側で動くのでブラウザから見れる
もまいの要求はブラウザから見れないプログラムなのだから
WebProg板へいってこい
281 :
デフォルトの名無しさん :2007/10/20(土) 18:50:18
>>280 ありがとうございました。
そういうことでしたか。
サーバとクライアント2台のマシンでメモリ上のデータを交換し ます。また交換したデータはサーバのディスクんき保存すると いうことをします。 この時、サーバにデータ保存する保証方法なんか みんなどうしていますか?RAID以外にどんな技術 組み合わせる?
信頼性を高めるのか?それなら単純にバックアップもするだけでいいと思うぞ まあ、板違いだけどな データが改ざんされてないか調べるならハッシュ関数つかうけどな
winsockなんだけど WSASendとかで引数でWSABUFを設定するところなんだけど int WSASend(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesSent,DWORD dwFlags,LPWSAOVERLAPPED lpOverlapped LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); サンプルを見るとdwBufferCountに1を指定しているのを見るんだけど 複数データを送信する時はlpBuffers配列で送信するほうが効率がいいの? 例えば10レコードのデータを送信する時など ループで10回実行するか、1回だけ実行するかで効率が変わるのかな? OSが勝手に送信バッファをいい具合に設定してくれる? 言ってる意味がわからんかったら言ってくれ、もうちょっと詳しく書く
>>284 それはいわゆるVectored I/O, scatter-read/gather-writeでしょう。
Unixでいうwritev()。
そうできるんなら、配列使ったほうが効率はいいはずだ。
writev()なら効率がいい上にatomicだが、WSASendがどうだかは知らない。
MSDNのヘルプをちらっと読んだけど、あんまその辺に触れられてないね。
0バイトのデータをsendする方法はありますか?
0バイトのデータをsendすることに何の意味が?
ping代わり?
connectをノンブロックで行い官僚をselectで待って write可能になったときにsendして成功するか確認 したいの・・・
0byte送って確認するのか。 斬新なアイディアだ。
いや、select()のない時代のUNIXはそうやったよ。 ノンブロックにして0byte write()。networkに限らず。
>>289 connectでwrite可能になったというのは3way handshakeがとりあえず
成功した訳だから改めて接続を確認する必要もないんじゃない?
>>290 tcp keepalive
>>292 write可能であっても成功したとは限らないの・・・
>>293 connect時の最後のackが届かなかった場合?
最初のsendでエラー処理をするんじゃダメなんだろうか?
そもそもsendが成功したら受信側にデータが届くって事が保証されてるの?
そんなことは聞く前にソケットFAQ読め。
297 :
292 :2007/10/24(水) 10:14:48
>>293 あっそうか、SYN,ACKを受け取ったらwrite可能になるか。
>>298 それってpassive openでしかも単にソケットをuser landにacceptで渡す
タイミングの話しでしょ? 289の質問はactive openだから全然話しが違う。
300 :
デフォルトの名無しさん :2007/10/25(木) 00:56:29
サーバー用のソケットは socketでソケット作成 bindでポート番号とかに結びつける listenで聞く??? acceptでクライアント接続を待ちの後 交信用ソケットにクライアント対応を任せ新しいクライアント接続待ち みたいな感じだと思うのですがlistenの必要性?がいまいちわかりません listenの引数をみてもソケットと最大コネクション数という感じであまりいい仕事?してるようには見えません どーしても必要ならsocketかacceptで最大コネクション数とやらを指定するようにすればよかったんじゃないのかなーと思ってしまいます listenがlistenとして独立していて幸せと感じるのはどのようなときなのでしょうか?
ソケットを接続待ちの状態にするためにlistenは必要。 第二引数は最大コネクション数ではなくて、キューの数だった気がする・・・ 要は一気に接続要求が来たときに待ってもらう数な。
データを送信した時に全データが送られないってことがあるじゃないですか。 これを明示的に起こさせる、起こしやすくするには、どうしたらいいですか? どんな設定をしたらいいですかね? setsockoption関数?で送信バッファを1に変えても変化なかったんですよね・・・ 全データ遅れなかった時の動作が確認できないんです・・・
>>300 listen で実際にサーバのポートを開く。
socket -> bind -> connect っていう手順もありうるので、bind だけではまだポートが開いてない。
>>302 受信側の受信バッファも小さくしてみたら?
あと、受信側が recv しなければ、そのうちバッファが一杯になって送れなくなる。
1秒に1バイトずつちまちま recv するようにしてみるとか、どうかな。
>>304 回答ありがとうございます
ちょうど今自己解決しました
送信データを1バイトずつSendしたらなりました
nagleを切ればいいだろ
>>306 やっぱり、全然無理でした。
どうやったらできるんだろ?
カーネルの送信バッファとsetsockoptで設定するバッファって同じことを指してるんでしょ?
送信バッファ 30バイト、送信データ100バイトとした時
send関数を使うと、戻り値が30と返ってくるって思ってるんだけど間違ってる?
ちなみに サーバをIOCPで実装しています。WSASend, WSARecvを実行しています
だから正確にはsend関数は使ってません
TCPのチェックサムって計算 仮想ヘッダ+TCPヘッダ+ペイロードだよね? 仮想ヘッダとTCPヘッダはいいけど ペイロードってどこまでなの? HTTPとかTCPの下になんかプロトコル付く場合 だけ計算みする
>>310 > ペイロードってどこまでなの?
全部(もしデータが奇数だったら1バイトの0x00を付加)
>>307 TCP/IP の下の NDIS (パケットドライバ)あたりが、パケットの非同期送信を
また別んとこのメモリの許す限りキューイングしてくれるから、そこいらへんは
あんまりあてにならない。
313 :
デフォルトの名無しさん :2007/11/02(金) 15:00:24
winsockでTCPでプログラミングをしているのですが、 たまに接続が上手くいかない時があります。 connect()を実行しても、タイムアウトになってしまいます。 一度プログラムを終了して、再度connect()したら普通に接続できます。 上手く行く時とそうでない時があるのですが、どのような事が原因として考えられるでしょうか?
たまたまサーバや回線が混雑してて繋がらなかったとかじゃないか WSAGetLastErrorでエラーの詳細を確認しる
315 :
デフォルトの名無しさん :2007/11/02(金) 15:16:06
>>314 connect()のエラーは10060でした。
多分タイムアウトだと思うのですが・・・。
while(SOKET_ERROR){
connect();
}
のような感じにしていて、常に10060が返って来ます。
ネットは色んなHPを見て回れるので混雑してるとかではないと思います。
↑のループをずっと繰り返している間に、新しくクライアントのプログラムを作ってサーバに接続を試みたところ、
普通に接続が出来たので、サーバが原因ではない事は分かってます。
316 :
デフォルトの名無しさん :2007/11/02(金) 15:31:53
connectに失敗した場合、closesocketをして、再度ソケットを作成、サーバのアドレスの設定等を行い、 その後またconnect()を実行する事で、サーバに接続する事は出来ました。 しかし最初にconnect()に失敗する前のsocket()関数は正常に終了しており、sockaddr_in構造体の設定も間違ってません。 connect()が失敗した際に行う再設定は、全く同じ内容のものなのですが・・・ 一体何が原因なのでしょうか・・・。
サーバは何?誰がどうやって作ったもの?
319 :
デフォルトの名無しさん :2007/11/03(土) 18:07:41
サーバは自分で作りました。これもC、Winsockで作ってます。
>>316 connectのエラーコードは何だよ。それくらい書けばいいのに。
321 :
デフォルトの名無しさん :2007/11/03(土) 19:50:06
>> 316 九割九分九厘名無氏作蟲
>>316 タイムアウトだから、
>>314 が言っているような感じなんじゃね?
起きている事象として把握できているのが、10060だけだと考えるのはキツイかも。
回線の種別(loopback、外部への接続)とか、connectの頻度とか、
connectがエラーになる接続先は常に同一なのかとか、その辺はどうなのだろう?
あと、クライアントとサーバと両方を自分で作っているのなら、connectと
acceptの数や時刻をログ出力して比較してみるとか。
いくつか考えうる要因をピックアップして調べてみては?
324 :
デフォルトの名無しさん :2007/11/03(土) 20:25:01
>>323 しかし、connect()に失敗したら再度connect()を実行するような設計にしています。
回線の混雑が理由だったら、いつかは接続できそうな気が・・・。実際はこの状態になるといつまでも10060を返し続けます。
また、10060を返してる間に、他のクライアントプログラムを実行しサーバの同じポートにconnect()を実行したら普通に接続できました。
もちろん同じPCからです。また、10060を返した後にソケット破棄⇒再生成してconnect()を実行すると接続できるので、
どうもネットワークの混雑という理由は考えにくいような気がします。とはいえ、ネットワークの問題は原因が特定しにくいので、
完全にそうではないとは言い切れないです。
connectの頻度はそう多くないのですが、まずサーバに接続し、その直後にもう一つ接続を作ります。
この2つ目の接続でconnect()エラーが発生します。2つ目の接続はファイルの送受信用のソケットで、スレッドを立ててそちらで処理しています。
なのでacceptとconnectの数は2回ですね。
325 :
デフォルトの名無しさん :2007/11/03(土) 20:40:58
もしかして、connect()を短い間隔で2回やってるのが原因なのかなと思って、 2回目のconnect()をする前にSleep(200)を挟んで何度か実行したところ、 connect()でのエラーはなくなったように思えます。(まだ試行回数が多くないので分からないですが) 短い時間で連続してconnect()を実行した場合、何が起こるんですかね・・・?
2MSL だろ
サーバのOSはWinXP ProとかHomeだったりするのかい
>>325 ファイアウォールのログは確認しておいてね。
329 :
デフォルトの名無しさん :2007/11/03(土) 22:26:00
>>326 winsockの仕様というよりも、TCPの仕様ですか・・・。
でも通信をクローズしてないのに関係あるんですかね?
全然詳しくないので何ともいえないですが・・・
>>327 OSはWinXP HomeEdition ver.2002 SP2です。
>>328 火壁のログの確認・・・ググってきます
>>324 まずは、ネットワークトレースを見てからだ。
10060なら、syn、syn-ackがどうなっているか確かめようぜ。
Linux使いなのでコード等よくわからんが、 ネットワークプログラミングのデバッグならパケットキャプチャだ。 WindowsならWiresharkがあるはず
332 :
デフォルトの名無しさん :2007/11/03(土) 22:54:04
Wiresharkだったらこの間入れたはず。 でも、英語だらけで使い方がよく分からずに放置した記憶が・・・! syn、ackってTCPの3wayHandshakeとかの話ですよね? そんなところまで見れるとはなんと便利なソフトなのだろうか。 とりあえず使い方から調べなおしてちゃんと根本から問題解決するか・・・
333ゲット
ところでみなさんGUIのネットワークプログラムを作るときは 非同期ソケットでスレッド1本派 同期ソケットでマルチスレッド派 のどっちですか?
335 :
デフォルトの名無しさん :2007/11/03(土) 23:34:09
なんとかパケットキャプチャは出来たけど、実際見てもよく分からないという現実!
http://kjm.kir.jp/pc/?p=45801.png No.10-12が多分最初の接続ですね。その後のポート5000がファイル送受信用の接続です。
ポート番号については突っ込まないで下さい><
最後の方で色々とsynとackを送りまくってますが、ここら辺がソケット破棄して再設定してconnect()してるあたりですかね・・・。
俺の知識じゃ、これ見て でっていう レベルなんですが・・・
よくわからんがNo.30とNo.50の 192.168.0.185:3739 -> 192.168.0.186:5000 に185が応答していないように見えるが。 ファイル送受信用、と言われても・・・そんなの話に出てきてないから・・・
XP Homeはサーバ用途が制限されていたような
338 :
デフォルトの名無しさん :2007/11/04(日) 00:01:49
>>336 >>324 で一応書いたつもりでしたが、ちょっとゴチャゴチャして見にくかったですねm(_ _)m
多分34、50、63のSYNを送ってサーバからの応答がないままタイムアウトになって、
ソケット破棄、ソケットの再生成と再設定⇒connect()が67で、その後の応答とかが68、69で
接続が確立してるっぽいですね。それ以降のものはファイル送受信のパケットだと思います。
見る限り、サーバからのACKが返ってこないようですが、クライアントからのSYNは送られてるんですよね。。。
サーバにそれが届いてないか、サーバに届いてるけど、サーバが送り返してくるSYN,ACKが途中でパケットロスしてるのか・・・。
>>338 ポート5000からの応答が無いな。そっちを調べるしかないだろ。
>>335 ポート5000ってのはナンダヨ。サーバー側のプログラムが悪いんじゃないのか。
341 :
デフォルトの名無しさん :2007/11/04(日) 00:29:10
>>340 ん、どういう事ですか?あまり49151以下の予約済みポートは使わない方がいいって事ですか?
とりあえずサーバ側のプログラムを再度見直してみます。
netlinkの使い方を日本語で詳しく説明してるサイトないかな? Manpage of NETLINK以外で
344 :
デフォルトの名無しさん :2007/11/04(日) 06:18:34
サーバ側が、50000番の接続要求に反応しない理由を調べたほうがいい。 1.サーバ上で、50000番への接続受付が満杯 2.サーバ上で、50000番がまだ再利用可能ではない(サーバ上で、netstatして50000番の状態を調べれ) 4.サーバが再起動した 3.パケットロスが発生してる(ローカルネットワークじゃ考えにくいと思う) 1,2,3,4の順で可能性は高いと思う
>>341 ファイアウォールのログは見てみた?
SYN floodか何かに判定されてコネクション要求がファイアウォールで破棄されていないかな、
と思ったんだが。
…もしかして、俺、考えている方向ずれてる? そうだとしたら、すまん。
クライアントとサーバのプログラムにログ出力を付け加えて、コネクションの確立の
様子を見るのもあり。connectやacceptの前後といった場所に、printf()で良いから
付け加えて、クライアントとサーバの両方の処理がどのように、どこまで出来ているのか
確認するってことで。
347 :
デフォルトの名無しさん :2007/11/04(日) 09:14:42
FreeBSD上でプログラムを組んでいて不思議な事に出くわしたので相談します。 IPアドレスを入力し、そのアドレスのネットマスクを取得するプログラムを組んでいますが、 ICMP_MASKREQを使って取得しています。しかし、AlliedTelesisのL3スイッチではきちんとICMP_MASKREPLY が返ってくるのに、CISCOのルータやPCだと応答がまったく返ってきません。 これはプログラムミスか、単にCISCOのルータがRFCに準拠していないのか・・・ どうでしょうか?意見をお願いします。
>>347 > CISCOのルータ
Firewallで捨てられてるとか? ルーターのicmpカウンタをチェック。
> PCだと
ホストは必ずしも答える義務無し。
349 :
デフォルトの名無しさん :2007/11/04(日) 11:22:08
>>348 ヒントありがとうございます、CISCOルータにて、ip mask-reply コマンドでMASKREPLY
を有効にしたところ期待通りにプログラムが動きました、デフォルトでno ip mask-reply
になっているようです。
PCでは答える義務無しですか、残念。
SNMP以外でネットマスクを取得する手段を考えていたのですが・・・
考え直してきます。
>>349 > SNMP以外でネットマスクを取得する手段
MASKREQUESTって聞いているホストが使うべきマスクを問い合わせるのに
使うのでしょう? 問い合わされたホストのマスクを返すのではなくて。
昨今はDHCPで取得される情報なのでほとんど使われない機能。
RFC1812はデフォルトで答える事をMUSTにしてるので、お前が設定したのだろう。
352 :
デフォルトの名無しさん :2007/11/04(日) 12:23:40
すれ違いで申し訳ないんですが、 googleでXXXを検索。 のように、webページに引数を渡す?みたいな事ってどうやればうまく できますか?
353 :
デフォルトの名無しさん :2007/11/04(日) 12:34:23
>>350 勘違いしていました、指摘ありがとうございます。
たしかにそうですね・・・、実験で確認がとれました。
MASKREQUESTで問い合わせたアドレスのネットマスクを取得する考えは根本から間違ってました。
>>351 ルータ初期化して試してみましたが、デフォルトでno ip masu-replyになってました。
ヒント:URI、クエリ、GET要求
355 :
デフォルトの名無しさん :2007/11/04(日) 13:53:11
>>354 ヒントありがとうございます!
大変助かりました!
>>353 iosのバージョンとかにもよるんじゃないの。
デフォルトのイメージが書き換えられてる場合もあるし。
おまいら、IOSとかCiscoの製品使える? やっぱネットワーク系のプログラム組んでる人間としてCCNAぐらい取っておくべきかな?
そんな暇あったら、カマー本やスティーブンス本読破すれば? 基本的な知識あれば、ルータ設定くらい簡単だよ。
自分の力に自信が無くて 資格を求めてるんだろ。 取るのを勧めてやるのが優しさだよ。 もっとも俺ならプログラムなんてもう辞めろと言うけどね。
>>351 RFC1812が書かれた当時とは実情が変わるなんて良くあること。
ciscoのマニュアルによると。
ip mask-reply
To have the Cisco IOS software respond to Internet Control Message
Protocol (ICMP) mask requests by sending ICMP mask reply messages, use
the ip mask-reply command in interface configuration mode. To disable
this function, use the no form of this command.
Defaults
Disabled <<<<<<
コマンドが導入されたのはIOS 10.0。
プログラマからみたIOSっていうとXMLみたいなもんだからなぁ
全然違うぞw
363 :
デフォルトの名無しさん :2007/11/10(土) 13:29:28
IPv4かIPv6かわからないときgetaddrinfoを利用し調べる方法が
ttp://ja.wikipedia.org/wiki/IPv6の下のほうに書いてありました Windowsではws2tcpip.hに宣言がありました
getaddrinfoへ渡したaddrinfoのai_addrを利用し、IPv4かIPv6のアドレスを取得すると思われるのですが
ai_addrの型はsockaddrでその定義はwinsock2.hにしかなくそれは以下のようになっていました
struct sockaddr {
u_short sa_family; /* address family */
char sa_data[14]; /* up to 14 bytes of direct address */
};
これだと8*14==112で、IPv6アドレスを表すための128bitに足りないような気がするのですが思い違いでしょうか?
sockaddr_in6にキャストしてつかうんじゃね?
sockaddr sockaddr_in sockaddr_in6 でググれ
FTPの同時接続数とレスポンスをまとめたサイト知ってる方います? 並列は3回線くらいがいいのかな・・・
環境によって違う。
>>363 もっとCの勉強した方がいい。
計算もできない馬鹿がいるって 聞いて飛んできました どこどこ? u_shortが8bitってどんな頭してるんだよw 染んでこいよw
氏ねとは言い過ぎだが レベルの低いやつは質問しない されても無視するようにしないか?
さすがに今ではshortが8bitってことはほとんど無いが・・・ 逆に16bitであり続ける理由も無いな
そう考えると結構恐ろしいんだよな プロトコルにつかう構造体はバイト単位じゃなくて オクテット単位か出来ればビット単位で定義すべきなんだよな
Cには2進表記すらない。 0b1_01110_00
>>371 殆どない、じゃなくて、規格上ありえませんが。
16bitより大きい可能性はあるけど。
現実を知らず 教科書しか読まない奴は レスしない方がいいよ。
377 :
375 :2007/11/10(土) 20:18:34
>>376 俺はあほじゃねーよ
落ちこぼれなだけだ糞が
せめてageたら?(藁
>>374 いやいや、あるよ。規格上でも char≦short≦long なだけだし。
intに至ってはもっとひどい
規格ではshortは-32767〜+32767を保証してなかったっけ?
>>380 ISO/IEC 9899によるとちゃんとその規定があるな
つか規格読んでもshort intとshortの区別がつかねぇ・・・
longとlong intの違いって何?
long long ago; ってそういうギャグを実現したかっただけ?
>>379 バカまるだし
shortは16bit以上、longは32bit以上が必須
どの規格のC? てかCじゃなくてC++?
>>382 >longは32bit以上が必須
さすがにこの嘘はオレでも見抜く
ずっと384のターン
知らないことは恥ではないし、バカにされる理由もない。 誰もが最初は知らないんだし、少なくとも俺は知らないという理由ではバカにしない。 恥なのは、知らないくせに知ったかぶって間違いをさらすこと。 嘘を言いふらして、周りにも迷惑をかけるし。
C89より昔のCプログラムはネットにつなぐな氏ねってことですかそうですか
>>388 発端となった
>>371 は、「今では」と言っているので、昔の話は関係ありませんね。
「今のCの規格」で、shortのサイズが決まっているかどうかですよ。
393 :
デフォルトの名無しさん :2007/11/10(土) 22:08:30
>>392 昔の規格が使用禁止になったわけじゃないしなぁ。
ていうか、使用禁止にしてほしい。マジで。頼むよ。
新規格を出せば後は野となれ山となれ
ふと思ったんだけど、C99ってみんなもう適用してる?
もう適用してる? (゚Д゚)ハァ?
>>397 冷静に考えたら適用って変な言い方かも。
つーか -std=c99つけるとコンパイル通らないコードとか
けっこう多くてさー
K&R2版のANSI Cに従って書いてる。 つもり
結局、 shortが16bitとは言い切れない時代の規格 が まだまだゾンビのように蔓延ってるってことか・・・やりきれんな
そんなの<limits.h>やsizeof使えば簡単に弾けるじゃん。
>>401 弾いてどうすんだよwww コンパイル通らないだろwww
そんなリファクタする暇と金は貰ってねーよwww サーセンwww
という人が多いというかほとんどだと思う。
弾いたら動かないだろw
>>400 のケースは新しく書いたコードをコンパイルするんでしょ?
希少な環境向けのコードは、必要に迫られてから実装すればいいのでは?
コンパイルの失敗を安全弁にしといて。
>>405 いや、無理だな
コンパイルが通ってしまって挙動が変わる のが怖すぎる
古ければ古いほどなおさら・・・ イァ イァ
#ifndef __STDC__ #error ばーか #endif つーか、まず「C89以前のコンパイラしかない環境」は無いし(GCC等のクロスも含めて) 例え「C89以前」だとしても、「それに加えてshortが16bit未満」なんてこと、ありえないよ。 世界中捜せば、pccを自分でコンパイルして常用している人くらいは居るかもしれないけどさ。
そもそも、C89、いわゆるANSI-Cだって プロトタイプやconst,voidなんかを導入したとはいえ、 「出来るだけそれ以前の処理系が規格違反にならないような規格」として作られたんだから。 intのサイズとか。
>>407 「C89以前のコンパイラしか使わせてもらえない職場環境」
は実在します
12bitのDSPが御座いまして
H8Sとか普通に使うんすけど
へー、みんな、そんなにshortが16bitに満たない環境を使ってるんだー すごいねー
ここはネットワークプログラミング相談室 いつからC言語信者が語り合うスレに・・・
407は自宅警備員?
うん
>>407 >「それに加えてshortが16bit未満」なんてこと、ありえないよ。
そういう世界に生まれたかった
今からでも遅くはないZE っ脳内世界
已 学 了的「long」修 尺寸。 其 「long」用 略了「long int」的 述, 那个意 成「与int型同 比那个大」。 在同 里(上)表示「与int型同 比那个 小的」「short」(short int 的省略)也存在。 ANSI C short 和 long 的字 幅度被 理器托付,象只以下一 地 定着。
つーか
>>384 を読んでくれよ。
ここの部分は馬鹿でも理解できる記述になってるから。
>>420 お前それは本気で言ってるのか…(゚д゚)
ほんとこういうくだらない話題のときだけは伸びるな
>>421 X3010ってC99のことじゃないの?
いやX3010のうちX3010:2003がC99相当
intのサイズはどうでもいいというか決まってないよね?
429 :
デフォルトの名無しさん :2007/11/12(月) 10:02:48
AcceptExの完了をGetQueuedCompletionStatusで捕捉できない・・・
その次のクライアントからの送信はGetQueuedCompletionStatusで捕捉できるのですが
第4引数のLPOVERLAPPEDはAcceptExに渡したのがきます。 ><
期待したのは
メインスレッドでAcceptExを呼ぶ -> クライアントがconnectしてくる ->
ワーカースレッドで呼ばれてたGetQueuedCompletionStatusが処理を返す -> クライアントが"Hello"と送る -> ワーカースレッドで呼ばれてた(ry
という感じなのですが
実際は
メインスレッドでAcceptExを呼ぶ -> クライアントがconnectしてくる ->
まだGetQueuedCompletionStatusから返らず@ワーカースレッド -> クライアントが"Hello"と送る -> ここで初めてGetQueuedCompletionStatusが処理を返す
となってしまします。
初めてGetQueuedCompletionStatusが返ったときのOVERLAPPED::InternalHighは5となっておりクライアントからの送信に反応したものと思われます。
AcceptExの完了を捕捉しないのが仕様かと思ったのですが
ttp://www.codeproject.com/useritems/iocpwalkthrough.aspのコードを見てみるとワーカースレッド内にswitch文内をみるとsend 、recvのみならずacceptも捕捉できることを
前提として書かれてるように見えます。 しかし実際コンパイルして実行してみるとやはり上記とおなじことになってしまいました。
いや仕様だし。
>>429 MSDN読んだら。
データを受け取るまで待ちたくないのなら、
dwReceiveDataLengthに0を渡すと良さげ。
432 :
429 :2007/11/12(月) 16:22:13
>>431 おおおおおお ありがとうございます
dwReceiveDataLengthに0を指定し期待していた動作を得られました
MSDNのdwReceiveDataLengthの説明のところにもろに書いてありました 不覚orz
VB.netのUDPの使用について質問があります。 2台のコンピュータ間で互いに自身の画面をキャプチャして相手に送るソフトを作っています。 それを送信して、受け取り、見ることはできるようになったのですが、外部ネットワークとの通信ではうまくいきません。 恐らく、データの重さから途中でパケットが消えているのだと思うのですが…。 流石に現段階よりもさらにデータを少なくすると、とても見れたモノではないので、 パケット分割をして送信しようと思うのですが分割方法がわかりません。 ※ローカルネットワークではできています。 送信はキャプチャ画像を一旦メモリーに保存し、それをbyte配列に直して送信しています。 TCPは通信する相手との問題で採用する気はありません。 もし、出来ている時点までのソフトウェアのソースコードが必要なら自サイトにアップロードしダウンロードできる状態にします。 開発環境はVB2005、通信相手とはUDPを使用した単純な文字列のみのチャットなら出来ています。 よろしくお願いします。
UDPでやっていちいち検証するくらいならTCPの方がいい
それかRTPを使え。
437 :
デフォルトの名無しさん :2007/11/13(火) 09:17:27
>433 ホールパンチングが必要ならTCPで外にサーバを立てろ。 遅延の問題ならTCPで多重化しろ。 単にFAQ読んでないだけだろ?
>>434-437 返信ありがとうございます。
パケットの分割でなんとかなるかと思いましたが、思いのほか他の方法でする回答が多かったので、一から仕様を変更しようと思います。
ありがとうございました。
FTPでQUIT発行してbyeした時に、通常なら受信したバイト数とかの情報を返してくるんだけど、 返って来ない場合があります。どう直せばよいのでしょうか? 221-You have transferred 0 bytes in 0 files 221-Total traffic for this session was 834 bytes in 0 transfers. 221-Thank you for using the FTP service on ftp4.geo.bbt.yahoo.co.jp. 221 Goodbye.
なぜここに?
HTTP1.0にしたらうまく動作したんですが、1.1ではなぜ出来ないんですかね?
Host情報送って無いんじゃね?
Host情報を送る際のコードが載っているサイトとかないですかね?
新宿2丁目と
歌舞伎町
郵便局
自力で調べろや坊主 って事ですか?
windumpでパケット調べろ。
GetTCPTableとかで取得したTCPコネクションを切断するにはどうすればいいんですかね?
452 :
デフォルトの名無しさん :2007/11/15(木) 21:09:01
HTTP1.1での通信方法がのっているサイトありましたら教えて頂けませんか?
Host情報を送ってHTTP1.1で通信するのは何も難しいことじゃないが今は1.0でええじゃないか きっとおまえさんにゃまだ早いんだよ
RFCも読まずにHTTPをしゃべろうという人を困らせるために、 サーバはPOSTに対してできるだけ 100 Continue を返すべき。 何かと思ってちゃんと調べるだろうから。
>>454 いや、いっそのことRFCそのものを返したらどうだろう?
でもHTTPとかContent Length義務にしてくれたほうがいいよなー もし最初の200バイトだけ送信して何もレスポンスがないまま5分たってから 残りを送信する仕様の(糞)サーバがあったとして、 Content Lengthが義務だったら待ちつづけるし。。。 あといきなりデータ送信終了してもcloseかけてくれない(糞)サーバがあったとしたら、 データがいつ終わったのか分からないし。。。
>>457 それどちらも Content length の有無と関係ないですよ。
いや例えば後者の場合、サーバがデータ送信終了してもクライアントでrecvの戻り値が0になるなり なんなりしなきゃ終わったかどうか分からなくないですか? Content-lengthあればrecvの戻り値が0であろうがなかろうがそこで自信を持って切れますし。。
>>459 えーとつまり「RFC違反だけど content length だけは正常に返す」という
サーバを救済できるから、content length を RFC で義務化すべき、
ということですか?
レスポンス開始時にはサイズが分からないので Connection: Close で返す、
というまともなサーバを実装不可能にしてまでやる意味があることとは、
あんまり思えないです。
そうだなレスポンス開始時にサイズが分からないこともあるか。 スマンカッタ でもRTSPとかはContent Length義務だよね。 そうしないとデータ境界わけわかんなくなるし。 こっちのほうがクライアント側がやりやすかったんで 言ってみただけだわ。
なんのためのチャンクだ
>>462 チャンクってRTSPにもHTTPにもないだろ?
TCP/IPソケット通信で質問します。 一度connectしたら常時接続のままという使い方をしてるんですが、 通常サーバ − クライアントどちらかでソケットcloseすると切断を検出出来ると思うんですが、 相手がcloseしないでリブートなどを行うと切断検出できません(無効となったソケットを維持) プログラムから一定間隔でping通信する 1通信毎にセッションを閉じる(頻繁に通信が発生するのであまりやりたくない) 空の電文を常時やり取りして生存を確認する もっとほかに断検出する良い方法があったら教えて下さい
>>465 TCPはそういうもの。
途中のルータが落っこちても一緒。
TCPとしては検出する仕組みをもっていない。
アプリで検出したくなければ、KeepAliveするぐらいかな。
>>464 >チャンクってRTSPにもHTTPにもないだろ?
はぁ?
>>465 > 空の電文を常時やり取りして生存を確認する
TCPはデータストリームなので、空のパケットは送れません。
1. データストリームの中のデータを型付けして、
通常データ以外に、alive check用パケットも送れるようにする。
2. keepalive socket optionを使う。(詳しくはFAQを
>>1 )
1.はICMP pingと違って、hostの死活でなく、
peerの死活を調べられるという利点があります。
>>466 「TCPが」というか分散環境ってそういうものだしね。
単純に落ちるfailure以外に、Content-Length: が違うなど、
mal-functional failureだって起りうる。
470 :
467 :2007/11/16(金) 13:08:15
まあchunkedなんてあんま使われてないけどな 自分で使うことはほぼ皆無だし
はぁ?
ム板で騙りとかどんだけ暇なんだよ
>>466 >>468 ありがとうございます。
2.のkeepalive socket optionを試してみます
keepaliveって検出までに2時間ぐらいかかるんじゃなかったっけ
設定できる。 Windowsはタスクごとに設定できる。
ほんとだチャンクあったんだ。 でもほとんど使われてないよねこれ。
え?apacheなCGIに1.1で喋りかけてみたら、Chunkedな応答を 戻されて焦ってRFC2616読んだ、みたいな経験はないの? delegateに1.1で中継してもらったら、ChunkedとContent-Lengthが同時に 戻ってきて、MLとかみるとどうみても意図的なRFC違反ですありがとうございました、 みたいな経験はないの?
>>476 脳内乙
君はプログラマに向いてません。
>>478 あっそwwww
じゃあ実際にコアな部分で使われてるオープンソースのプロジェクトを10個くらい挙げてみてよ。
RFCに準拠させるために実装が必須なサーバは除くよ。
Google code searchも知らないし、 Google APIも使ったことないし、 本当にプログラマじゃないんだろ。 荒れるから放置しる
例えば2chの.datを全取得する時、大きなものは当然のようにchunkedで返ってくるんだけど
もう一つ HTTP/1.1またはKeep-Aliveで、複数の、 CGIやSSI等のContent-Length不明な物を連続してGETすると mod_deflateによる圧縮が無ければ、当然chunkedで返ってくるね。 >481のは逆に、圧縮時に圧縮後のサイズが64Kを超えた場合のみだけど。
ごめん嘘だ。 HTTP/1.0だったら、Keep-Aliveでも chunked使われるわけ無いな。強制切断だね。
最近のHTTPライブラリでchunkedサポートしてないのは皆無といっていいし、
HTTP系のRPCは全部chunkedサポート前提だろ。
>>480 にあるGoogle APIとか。
chunkedって実装がめんどうなんだよなあ。。。 俺はCGIは全出力結果を取得してからcontent-length付きで投げる派
余程レスポンスがでかくなければそれでもいいんじゃね
>>485 CGIの場合は特に何も考えずにただ出力すれば
HTTPサーバが勝手にchunkedにしてくれるぞ
>>487 受け取る側の実装が、さ>めんどくさい
ところで一般的なデータの送受信を行う際に、
効率の良いやり方はどんな感じなんだろう?
TAP <--> NIC <------------> NIC <--> TAP
のようなtap間のやりとりをするプログラムを作っているんだが、
max = MAX(NIC,TAP);
while(1){
FD_ZERO(&read);
FD_ZERO(&write);
if ( 出力バッファ > 0 ) FD_SET(NIC, &write);
if ( 入力バッファ > 0 ) FD_SET(TAP, &write);
FD_SET(NIC, &read);
FD_SET(TAP, &read);
select(max+1, &read, &write);
if ( FD_ISSET(NIC,&read) ) NICから入力バッファへ
if ( FD_ISSET(TAP,&read) ) TAPから出力バッファへ
if ( FD_ISSET(NIC,&write) ) 出力バッファをNICへ
if ( FD_ISSET(TAP,&write) ) 入力バッファをTAPへ
}
単純に考えたらこれなんだけど、他に何か工夫あるかな?
>>受け取る側の実装が、さ>めんどくさい そのレベルならWinInetでも使ってろ Winならだが
無知なだけだろ。放置しる
俺には
>>488 のどこが釣りなのかわからん・・・
誰か解説plz
selectの引数の数は合ってないし、返値もみてないのに、 律儀にmax取っていたり、釣りか間抜けとしか思えん。 効率とか言っちゃってんのワロス
>>494 省略しただけだろ
エッセンスの方を見ろよ
おいしい成分は何ひとつありませんでした ちゃんちゃんw
epollを使ってて、切断を検出したいんだけど、 EPOLLOUTが帰ってきたあと、recv(...) == 0だったらclose。 という流れを使ってるんだけど、 EPOLLHUPを使って切断って検出できない?
498 :
デフォルトの名無しさん :2007/11/19(月) 10:16:40
Linuxでプログラム書いてますが、 ソケットの状態を取得する関数はありますか? getsockoptは状態ではなく設定を取得する関数なので要領を得ません とりあえず、接続中か接続済みか未接続かを ソケットディスクリプタから得るだけでもいいです
>>497 やりたいのはずばりEPOLLRDHUPでのedge triggerちゃいますの?
>>501 エッジトリガっていうのかどうかわ解らないけど、
向こう側でソケットをcloseしても、こっちにHUPが飛んでこないんです
向こう側がcloseしてソケットを閉じたら、HUPが飛んできてほしい。
飛ばない仕様になってるならrecv==0を使うけど。
誰か詳しいひとおせーてください
solarisで開発してるんだけど、 ノンブロッキングモード(?)でrecv()の戻り値が -1なんだけどerrnoが0になるんだが・・・ これってどういう状態なんでしょう? 期待値としてはEAGAIN(?)だと思ってるんですが。 ソケットプログラミング素人にどなたか救いの手をorz。 ちょっと困ってるんでageで。
errnoよりperror()が使いやすいよテスト
>>506 EAGAINの度にエラー吐かれたらたまらんぞ。
そもそもエラってるのにerrnoが0? 差し支えなければ前後のソースを少し晒してくれると
509 :
506 :2007/11/21(水) 11:12:59
>>508 ありがとうございます。えっとソースは抜粋&中略ですが、
大まかな動きはこんな感じです。
現象としては2kbyte程度のデータを流すと一度に取りきれないので、
selectで再ループして残りを取得する動作を期待しているのですが、
2回目以降のrecv()が-1となるのですが、errnoがEAGAINにならないので
エラーになって回線を切ってしまいます。
試しにEAGAINと0を対象として(コメント部)selectするようにしたら、
ちゃんと残りのデータを取る事が出来ました。
while( iLeftOver > 0 )
{
/* 指定バイト数を受信、または通信の遮断まで受信データを取得 */
errno = 0;
if( ( iRcvRet = recv( stSocket, pcBuff, iLeftOver, iFlag ) ) == DCC_SOCKET_ERROR )
{
printf("iRcvRet[%d]/recv()直後errno[%d]\n", iRcvRet, errno);
iErrCode = dwp_getErrNo();
if( EAGAIN == iErrCode )
//if (( EAGAIN == iErrCode ) || ( 0 == iErrCode ))
{
/* 受信準備ができていない場合、selectで受信するまで待つ */
FD_ZERO( &stFdSet );
FD_SET( stSocket, &stFdSet );
dcc_setTimeval( 1000, &stTmVal ); /* 待ち時間は1秒 */
510 :
506 :2007/11/21(水) 11:14:48
(一回で送れませんでした。続きです・・・) iSelectRet = select( FD_SETSIZE, &stFdSet, NULL, NULL, &stTmVal ); if( iSelectRet == DCC_SOCKET_ERROR ) { /* selectのエラー */ (中略) return DCC_SOCKET_ERROR; } if( iSelectRet == 0 ) { /* タイムアウト */ (中略) return DCC_SOCKET_ERROR; } /* 受信を検知 */ continue; } /* 受信エラー */ (中略) return DCC_SOCKET_ERROR; } else if( iRcvRet == 0 ) { /* 通信の終了 */ (中略) return 0; /* 通信の切断 */ } /* 一度のrecvで受信し切れなかった場合、受信サイズ、バッファの位置を書き換えて 再度recvを行う*/ iLeftOver = iLeftOver - iRcvRet; pcBuff += iRcvRet; }
511 :
506 :2007/11/21(水) 11:17:40
あまり意味ないけどコンソール上には >iRcvRet[-1]/recv()直後errno[0] 表示されてしまいまふ。
#include <errno.h>はインクルードしてますか? (必要なOSの場合に; 今時pthread絡みで必ず必要だけど) 自分でextern int errnoしてたら殺しますよ。
errno=0をerrno=100にしたら100のままだったりしてねw
Linux&(C or C++)でhttps通信を利用したプログラムを作りたいのですが、 httpsを利用できるライブラリは無いでしょうか。 ghttpがあったのですが、httpsには対応していないようで困っています。
515 :
506 :2007/11/21(水) 15:25:02
>>512 errno.hはインクルードはしてあります。
その直後にextern int errnoもしてました。
これは不味いんですか?
恥ずかしながらUNIXはホントわからないんです・・・。
>>513 まさにその通りです。
recv()の前後でerrnoの値が全く更新されません。
と、言うことで「extern int errno」の行を削除して
みたのですが現象は変わりません。
その書き込みから見ると非常に基本的な部分で間違いが
あると思いますがなんとも分かりません。
他に考えられる原因はありますでしょうか?
その他のソース部分には、errno.hのインクルード等は
されていません。
ちなみに動作環境はsolaris8、開発環境はeclipse+CDTで、
コンパイラはgccのVer2.8.1を使ってます。
厨な質問で申し訳ないです。m(__)m
>>515 errnoが通常の変数の場合、マルチスレッド環境だと、errnoを取得する前に別スレッドが書き換えてしまう
ケースがあり、正常に動作しないので、
最近のOS/ライブラリでは、#defineで「errno」をスレッドごとに確保された記憶領域へアクセスする関数に
置き換えてる。
517 :
506 :2007/11/21(水) 15:58:11
>>515 お付き合いありがとうございます。
要は「#include <errno.h>」のみやれば良いとの認識で
良いでしょうか?
manpageによると
------------------------------------------------------------
errno は、ISO C standard で int 型の変更可能な左辺値として
定義されており、明示的に宣言を行ってはならない;
errno はマクロの場合もありえる。 errno はスレッド毎に値を持つ。
つまりあるスレッドで errno が設定されても、他のスレッドの errno には
影響しない。
------------------------------------------------------------
とありました。
しかし、#include <errno.h>をしているのは、
私がUPしたソースのあるファイルのみでしか宣言してなく、
マルチスレッド環境ではありますがこのソースは、
単一のスレッド上でのみ動きます。
(上の説明からだと複数で動いててもそれぞれ独立してerrnoを
持っていると言う事になると思いますが。)
にも関わらず
>>513 のような挙動になるのは何故なんでしょうか?
どこか別のヘッダ等でexternとかしてるんでしょうか・・・
だから俺には短期間じゃ無理な作業だと言ったのに(T。T)>>会社
と、愚痴をこぼしてみる。スイマセン。
とりあえずな、
>>506 の言う通り、
perror()をprintf("iRcvRet〜の前に付け加えてみな。
後ろじゃダメだぞ。
519 :
506 :2007/11/21(水) 16:48:59
>>518 ありがとうございます。perror()を使用したところ
>>recv(): 資源が一時的に使用できません。
と返ってきて、EAGAINである事が確認出来ました。
と、なると後はなんでerrnoが変更されないのかですね。
一歩前進(?)しましたありがとうございます。
絞る知恵もなくなったので、ネットで検索しまくってます。
環境のせいかもね 1. errno.h にバグがある 2. インクルードしている errno.h のパスがおかしい 3. ライブラリとコンパイラが不整合
ネットワーク関係なくなってきてるが、 #include <errno.h> int geterrno(void) { return errno; } これだけのファイルをgcc -Eしてみな。 int geterrno(void) { return (*__アドレス返す関数名()); } にならないとまずい。 なってるならソースコードのerronoをgeterrno()に変えて終了。 左辺値参照はどうせまともな意味のあるコードないだろうし。
gcc 2.8.1ってなんだよ… 2.95.4とかなら分かるけど。 窓から捨てろ
523 :
506 :2007/11/21(水) 22:35:07
>>520-522 お返事遅くなってしまいました。
すみません&ありがとうございます。
>>521 明日試してみます。
>>522 用意されたサーバのを使ってるだけなので
私はどうにも出来ませんorz。
察するに「古くて使い物にならねー。」って事で
良いでしょうか?このあたりも原因あるのでしょうか・・・
ソケットなんて昔からあるので大丈夫な気もしますけど。
スレ違いにもなりかけてるので、以上を踏まえて精進します。
皆さん長々とお付き合い下さってありがとうございました。
感謝します(-人-)
サーバ上のCGIに文字列を渡して、その文字列を保存しようとしてるのですが 日本語等の2バイト文字を渡すと正常に受け取ってくれません。 char *mozi = "test.cgi?,testあ" hRequest = HttpOpenRequest( hHttpSession, "GET", mozi,//■CGIへ渡す文字列です NULL,NULL,NULL,0,0); 上記では「testあ」という文字列をCGIに送信していますが、CGI側では 「test0x000000000008p-10224」 という風に2バイト文字のみエラー認識されてしまいます。 どうすればCGIに2バイト文字を送信できるのでしょうか?
%82%A0%82%D9
char *mozi = "test.cgi?,test%94%C2%88%E1%82%A2" hRequest = HttpOpenRequest( hHttpSession, "GET", mozi,//■CGIへ渡す文字列です NULL,NULL,NULL,0,0);
>>525 >>526 >>527 検索してみた所、それらしい参考文献が見つかりました。
早速実装して試してみたいと思います。ありがとうございました。
%82%A8%82%DC%82%A6%82%E7%90e%90%D8%82%BE%82%C8%82%97
%8E%C0%91%95%8A%AE%97%B9%81%41%8A%B4%8E%D3
エンコード状態で会話すんなwwwwwwwwwwww
socket通信しているときに、相手方が shutdown(s, SHUT_WR) した時、 こちら側ではselect()から抜けて、read() で検知することができますが、 その後、相手が close() または shutdown(s, SHUT_RD) したことを 検知することはできないでしょうか?
>532 writeが-1を返すとか。 selectのexceptfdsが反応するとか。
536 :
532 :2007/11/29(木) 02:22:04
>>535 exceptfds は、相手方がMSG_OOBでデータを送ってくれないと
反応しないですね。
write は確かに-1 (EPIPE) を返してくれるのですが、こちらから
送信するときに分かるけれども、相手がcloseしたタイミングで
検知できるわけではないので、
難しそうですね。ありがとうございます。
というか、先に向こうがSHUT_WRしているんだから、 こっちはwriteしかできないわけだし。気にくわなければ すきなだけwriteして、むこうがSHUT_RD(残りclose)を発行する 前に、こっちからcloseしてやれば?
なんか失恋とか離婚とかそんな勢いだなw
Linuxでサーバプログラム書いてるんだけど acceptする前に相手のIPとポートを知る方法ってある?
541 :
539 :2007/12/01(土) 19:52:23
>>540 アリガトウ
そういえばそうだったね 忘れてた
送られてきたパケットのIPヘッダー部分を生ソケットでパースすればいけそうだけどね 俺はヘッダー処理を書いたことはあるが、パース処理までやる気はまだない
ヘッダー処理って何んだろう パース処理ってのがIPヘッダの解析なら 別に何にも難しいことないだろ
バカには難しいんだよw
どこにも難しいとは書いてない件について
ちょtぅwwwwwwwww 何そのやる気0の他力本願寺は
バグを発見したときは、 ・発生時刻 ・バグの詳細 ・(できるなら)一次解析結果 を調べるのは常識だぞな
Debug Assertion Failed! File:c:\program files\microsoft visualstudio 8\vc\atlmfc\include\atlcomcli.h Line 154 と出ます。
マジレスして良いのか分からないが 取っ掛かりぐらい自分でつかんでから人に聞かないと頭には入らない
質問があります。 accept で得たソケットをOVERLAPPED 対応にさせるにはどうしてます??
acceptで得るのはlistenに渡す奴のコピー(同じ性質)みたいなもんじゃなかったか
pMyBr->GoHome();を消したら、ウィンドウだけは表示出来ました。 …原因が、わかりません。
>>554 返信ありがとうございます。
listen ソケットに WSA_FLAG_OVERLAPPED が設定されていれば、accept で得られるソケットにも同フラグが設定された状態になるんですね。
助かりました。ありがとうございます。
解決方法はありますか?
atlcomcli.h中の154行目 ATLASSERT(p!=NULL); に何かしらの原因があるんですかね?
age
man 2 send を読むと、MSG_DONTWAIT について、 「fcntlのF_SETFLでO_NONBLOCKを指定することによっても有効にできる」 と書いてあって、これって、O_NONBLOCK にしてなくても、sendするときの オプションで MSG_DONTWAIT を使えば非ブロックモードにできる、という意味だと 思うけど、 逆にO_NONBLOCKになってるソケットでブロックモードでsendしたいときに send時のオプションで何とかならない? fcntlでO_NONBLOCKをクリアしないとダメ?
全然関係なくてあれなのですがboost::asioがIOCP使ってるぅー
本当にどうでもいいwww
私は
>>547 ですが、
ヒントだけでもいただけないでしょうか?
少なくともエラーメッセージから何でエラーが出るのかくらい考察しろ
>>558 翻訳:
pがヌルポでどうしろっていうんだよ、バーカ。
俺バカなんで教えていただけませんか?
>>555 ヌルポなんて渡すんじゃねえ、"Go home!"ってことなんじゃないか?
いったん家に帰って、必要な初期化を見直せ。
というか技量にあってないんだと思うが スレ違いかどうかすら判断できてないだろ
訳若芽
通信対戦ゲームのマッチングプログラムをperl/cgiで作っています。 cgiの中身は、掲示板のサンプルリストに毛の生えたような単純なもので、 何も無い部屋に登録すると、登録した人のIP、開放しているport番号を記録し、 そのクライアントはサーバー状態で接続を待ちます。 次に、他の人が登録してある部屋に入ると、登録してあったIPとport番号を 受け取り、サーバー状態で接続を待っている相手に、接続を試みるというものです。 実際作って、ちゃんと動いているのですが、そこでどうしても気になるのは、 登録しているIPとport番号を相手に受け渡す時で、やっぱり、 IPとport番号は暗号化して渡したほうがいいのでしょうか? 初心者向けのperlのCGIの本を読んでても、掲示板の作り方ぐらいで、 マッチングサーバの作り方については書かれていませんし、 同人ゲームのひぐらしデイブレイクの通信対戦では、堂々と掲示板に 自分のIPとport番号をさらしているので、それに比べれば、 目に見えない形でやり取りしているから、気にする必要は無いでしょうか? ものすごい初歩的な質問かもしれませんが、よろしくお願いします。
>>570 途中の盗聴を気にしているのならsslとかを使った方が良いかも。
サーバやクライアント自身に相手のIPやPort番号を知られたくないわけじゃないよね。
鯖--倉A | 倉B 接続状態が鯖経由なら、暗号化うんぬんの前に、 相手のIP,Portを教える必要はない。 鯖 倉A / 倉B 接続状態が直結なら、 何をしようと相手のIP,Portが分かる。
マジ訳若布 ググりまくったけど訳若芽 初期化方法わかんね
575 :
デフォルトの名無しさん :2007/12/04(火) 23:01:27
>>570 変なポートでなければたいした問題ではないだろ
openSSlとか使い切れなかったら
IEコンポ経由でアクセスすると楽だよ
576 :
デフォルトの名無しさん :2007/12/04(火) 23:07:44
ごめん,質問 PROXYの情報取りたいんだけど最適な方法は? レジストリに書かれている方でなく PACファイル等のスクリプトの方 IEコンポかMFC?(.NET) できたら WIN APIが助かる
IEだったら↓に自動構成スクリプトのアドレスが入ってる HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\AutoConfigURL 後は普通に読めばいいんでないの
ProxyServerは?
579 :
570 :2007/12/05(水) 21:43:43
返答遅くなってすみません。
また、いろいろアドバイスしていただきありがとうございます。
SSlですが、自分のCGI参考書ではグラフィックカウンターを作る説明しかなく、
これでどう暗号化するか分かりません。
RadiusもWikipediaで調べましたが、自分の頭ではチンプンカンプンでした。
ゲーム自体は、クライアント同士をP2P通信でつなげて遊ぶもので、
ipとport番号のやり取りのマッチング部分だけ、webサーバ上の
cgiで、C/Sで行います。
p2p通信で、しかも、マッチングにCGIを使うので、クライアントにも、
webサーバにもIPやport番号は知られるのは当然なんですが、
よく「iPとport番号は知られるとまずい」とか、
「ネットゲームの通信は暗号化しとけ」みたいなことが書かれるので、
webサーバから相手のIPとport番号の受け渡しのさい、暗号化する必要が
あるんじゃないかと思ったのです。
開放するport番号はプライベートport番号の間でなら各クライアントが
好きな番号を開放するようになっているので、49151番以前のportは
開くことはありません。
>>575 さんがいうように、
IPとport番号をそのまま受け渡しても、心配する必要は無いんでしょうか?
なんか文章が変ですみません。
なんでNULLが返されるんだぁああぁぁ!!!! ひぇぇぇぇうぇぇええ!!!! すみませんでした。 もういくら考えてもわかりません。 お願いします。この通りです!!!
SSI と SSL は違うよっ
暗号化する価値はほとんど無いな。 その手の奴がパケットの中身を見るまでもなく、 セキュリティソフト(ファイアウォール)が警告を出したりするから 一般人にだってIPとPortが分かるぞ。
というか、誰でもそのCGIを叩いたらIP:PORTがわかるわけで、 通信路を暗号化する価値がないような。
プロクシーサーバを作るとしたら、RFCの何番読めばいいんだっけ?
つ HTTP 1.1
Cで分割ダウンロードってどう実装すればおk? わざわざパケット操作まで階層下らなきゃいけないのだろうか…。
WinならwinmmのHttpQueryReauestでも使ってろタコ それ以外の環境ならsocket一手
wininetだたorz
>>588 > それ以外の環境ならsocket一手
libhttp, libcurl, libneon, libsoup 好きなのをどうぞ
>>590 UNIXだぜ。
socketをどうすればいいのか知りたいのだ><
ん?ひょっとしてlseekが効くのか…?試してないが…。
>588
libhttpにはそんな便利なAPIがあるのか…ぐぐってみるわ。
でもどうやって実装してるんだ?かなり低階層まで降りてそうだ。
httpの分割ダウンロードってrange指定したrequest並列に投げるだけだろ…
TCPのcwndとssthreshの値をみる方法ってない? 環境はfreebsdです
>>577 あんがと。だけどスクリプトの場合 Javascriptで
条件式とか入ってる場合があるから困る。
今はsocketでデーター出してるけど
素直に、NETかIEコンポのライブラリ経由でデーター
出した方がいいんだろうか・・・
>>579 >よく「iPとport番号は知られるとまずい」とか、
>「ネットゲームの通信は暗号化しとけ」みたいなことが書かれるので、
うちは、こんな事言ってる奴が多いので実害がなくても
簡単なスクランブルかけてる。少なくともテキストが読めない程度の。
596 :
デフォルトの名無しさん :2007/12/09(日) 23:17:21
できあいの物を利用したお手軽マッチングサーバー〜〜 用意する物 ■ WEBサーバー そこらのHP公開できるレンタルでOK ■ FTPクライアントライブラリ、MFC.デルファイでもOKです 1)ログイン時 自分のIDをファイル名にしたテキストファイルをFTPでアップします テキストの内容は自分のIPとポート番号です 自分のグローバルは確認君系のCGIで調べます 好みにより書き込むテキストは適当にスクランブルしましょう 2)接続時 接続したいIDの名前のテキストファイルをダウンロードします。 NotFoundの場合は「該当するIDは・・・」とか適当に出します 追記 余裕があれば UPnPで使用ポートをオープンしましょう UPnPはXML+Socketで行えばSP2のチェックマークを無視します 上級偏としてStunもありますが昨今使えませんので ゲーム程度ですとSkypeを使うのも吉です 結論 SkypeP2P使え!!
va_argsってスレッドセーフ?
実質自動変数(引数)へのポインタという意味合いの代物だから、 スレッドセーフ。もちろん、そのまま他のスレッドに持って行ってはいけない。 で、どこがネットワークプログラミングなんだろ。
ポートを解放しないとできないことっていったい何なんですか?
600 :
599 :2007/12/13(木) 00:28:07
なんか曖昧ですね。すいません。 例えば、htmlサーバーではポート80番は常に両方向解放されていて、 (他の問題がなければ)クライアントからのコネクションに成功しますよね。 クライアントのWAN→クライアント自身方向へのアクセスは許されていませんが、 サーバーにリクエストを送ることもその結果を処理しブラウザで表示することもできるわけです。 そこで質問なのですが、クライアントのWAN→クライアント自身方向への アクセス解放(ポート解放)をしないとできないことというはいったい何なのでしょうか?
>ポートを解放しないとできないこと LAN内のPCのポートとルータのWAN側ポートが関連付けられてないから WAN側からの接続を受け付けられない
ってか自分で言ってるじゃねえか ポートが開いてないとApatch起動しても外からアクセスできない
Apacheはサーバーなので質問の主旨とは外れます
>>600 クライアントのWAN→クライアント自身方向への接続ができない
>>601-605 TCPならクライアントへのconnectに失敗、
UDPだとsendに失敗(?)ということですか。
サンクスです。
ちげえええええええええええええええええええ connectすんのはクライアント側だ サーバはacceptだ UDPならrecvfromだ 根本的にソケット関係のマニュアル読み直した方がいい
たぶんクライアントの定義が違うんだよ
>>607 「クライアントがWAN側からの接続を受け付けられない」ということは、
サーバーがクライアントに対してconnectするときに失敗するという意味ではないのですか?
OK。落ち着け ネットワークプログラミングにおいて 「クライアント」は「接続しに行く側」 「サーバ」は「接続を受け付ける側」 だから
>>609 あなたのサーバとクライアントの定義をききたいよ
UDP は受け取る側がクライアント、というプロトコルも多いな・・ RTP とか
>>611 俺は
>>609 ではないが、
・LAN内のPC → クライアント
・WAN側のPC → サーバー
だったりしてな。
>>610 ,611,613
自分の解釈では
・サーバーはサービスを提供する側
・クライアントはサービスを享受する側
ですね。
ただ元の質問は、
「サーバーのポートが解放されていてクライアントがポート0の場合、何かできないことがあるのか?」
というものなので、ここではこの文脈にそって言葉を使っています。
元の質問ってそんなのだっけか? というかクライアントなのに自分でポートを開けておく必要なんて無いよな サービスを提供するためにポートを開けておくわけだし
クライアントからport80で接続されているときに そのconnectionを使って逆にサーバー側から クライアントに突撃する方法を聞いてるんじゃない?
たんにP2Pの存在をしらないんじゃ?
sshでトンネル作ってport forwardingしたらなんでもやり放題だお
619 :
デフォルトの名無しさん :2007/12/19(水) 10:14:58
netstatなんかで見れるような ソケットの 現在のステータス(ESTABLISHEDとかTIME_WAITとか) って、getsockoptでどうやって取得するの?
>>619 connectしてるかどうかくらいはわかるけど、普通見れない。
netstatは(setuidされていて)kmem見てたり、/proc/net/ 見てたりしてるだけ。
621 :
デフォルトの名無しさん :2007/12/19(水) 22:00:37
epollやkqueueはなぜ高速なのか、レガシなAPIとの比較で3行で教えてください。 特にepollに興味があります。
/dev/poll を忘れんなよ
要するに状態を監視したいソケット連中ってのは、selectの呼び出し毎に 大きくかわったりはしない。なら、引数でソケット全部を毎回渡すよりも、 ハンドル経由で差分更新したほうが、処理は高速になるって話。
計算量で語ってほしい
selectなら o(n) epolなら o(1) ってことだろおうぉあ
実際は、イベント発生頻度Mにも比例するから、 selectはO(N*M)になる、のかなー? epoll系はO(M)で。
>>623 621とは別人です。
10行になっても良いので馬鹿にもわかるようにお願いしますm(_ _)m
「大きくかわる(大きい?小さい?)」「ハンドル経由(ハンドル?)」がわかりません
628 :
デフォルトの名無しさん :2007/12/20(木) 00:27:48
klabという会社の勉強会資料が読みやすかったような記憶。 /dev/pollってなんだ?
京急の特急に乗ればいいことが解った
632 :
デフォルトの名無しさん :2007/12/22(土) 23:54:42
>>632 たぶんTransfer-Encoding: chunked
HTTPじゃないから、chunkedは関係ない。 どっちかってーと、MTUの話。 というか、ローカルだろうと、TCP経由で 一度に全部読めると思うのが間違い。
なんだそうか
頭痛いわ
つ バファリン
股間が疼くわ
つ クラビット
可能です マルチスレッドとかノンブロッキングとかIOCPとか調べるよろし
ありがとうございます。
643 :
デフォルトの名無しさん :2007/12/24(月) 00:35:48
非同期モードと非ブロッキングモードはどう違うのですか?
まずお前がその二つをどう理解しているかを述べよ
たとえば読み込み指令を出して、そのときには読むべきデータが無かったとしたら、 ノンブロッキングはすぐに諦めて帰ってくる。 非同期は何かが読めるまでバックグランドでがんばってくれる みたいな違い。
その理解でいいんじゃない? 順序としては ブロッキング → ノンブロッキング → 非同期I/O と進んできたんだけど これ以上詳しく知りたければ実装を調べるしかないのではないかと
リクエストとリプライが同時でない=同期的でないのが非同期。 リクエストを出した後、リプライは後から別の手段で得る。 一対一に対応してないこともある。リプライが続々とやってくるなど。 ノンブロッキングは同期的だけど、データ取得を諦めることがある。 その時でも「データねーよ」とのリプライが同期的に得られる。 非同期はそうではない。
使い分けで 同期-ブロッキング 多重化-ノンブロッキング(select or poll) 非同期-シグナル駆動I/O or 非同期I/O とあったのですが、 これで合っていますでしょうか?
>>648 > 非同期-シグナル駆動I/O or 非同期I/O
も多重化出来るだろ。
たじゅーか! と書くとほほえましいな
Linuxでクライアント書いてるんだけど closeが完全に終わるまで待つにはどうしたらいいかわかんないので 誰か教えれ
shutdownで半クローズ → 相手にEOFが届く → 相手がソケットを閉じる → EOFが来る → こっちも閉じる とかじゃだめなん?
>>652 だめじゃない!だめじゃないぞ!いける!
それはさ、こっちの最後の送信結果が、closeしちゃうと判らなくなるからで、 別にこっちが送信してないなら勝手にcloseして終わりにしたらいいじゃん。
655 :
デフォルトの名無しさん :2007/12/25(火) 14:18:46
非同期モード、非同期イベントを利用して localhost上のバイナリファイルをダウンロードしようとしているのですが、 ブロッキングを起こしてしまいます。 非同期モードを解説したサイト等ありましたら、 教えてほしいです。
656 :
デフォルトの名無しさん :2007/12/25(火) 14:54:45
657 :
デフォルトの名無しさん :2007/12/25(火) 18:23:18
WSAAsyncSelectでググったらいくらでも出てくるじゃねぇか
ここは書き込めるようだな
というか、その「ブロックを起こす」コードを晒してみたら?
自己解決しました。 ありがとうございます!!
どういたしまして
662 :
デフォルトの名無しさん :2007/12/25(火) 23:27:54
ARCNETは、スレ違いですか?
いいや、違わない なんなら422でもCANでも構わない
>>664 >こちらからサーバにデータをPOSTする処理をfor文を使い連続でしたいのですが、
できません。それが非同期処理。
キューなりリストにPOSTするデータを入れておいて、
FD_WRITEが取れたら書き込む。エラー処理も忘れずに。
どうしてもforでまわしたいなら、
スレッド分けて、WSAGETSELECTEVENTするスレッドで、FD_WRITEがきたら、
イベントをセットし、POSTするスレッドのfor内でそのイベントをWaitForSingleObjectするとか。
でも、それなら最初から同期処理で良い。
とりあえず、-1がもどってくるまでは無条件に書き込めばいいんでないの。
667 :
デフォルトの名無しさん :2007/12/31(月) 15:59:49
教えてください。 サーバソケットでTCPの10〜100バイトの可変長データを受信する際、 そのデータのレングスが先頭2バイトにある識別子で判断できる場合って ・まず先頭2バイトをrecvする。 ・識別子を判断して残りのバイト数をrecvする というのが一般的なのでしょうか? recvの第3引数に1500バイトくらいの十分余裕な値を指定すると 勝手に1データの終わりを検出してリターンしてくれるものなのでしょうか? 要は連続してデータが飛んでくる場合に 1データの区切りをrecv1回で済むのか、2回に分けないといけないのかが 知りたいです。 Linux環境です。
読みたいなら読めばいい。場合によっては、区切りを検出してくれることもある。 ただ、「1500バイトrecvをかけて、1400バイト読んだ。ヘッダのレングスは500バイトだったよ〜」 ってときもあるから、500処理したあとに次のヘッダ処置にいかないとダメだし、 その逆の、「ヘッダは500バイトあるっていったけど、recvで戻ってきたのは200バイトだった」 って言う場合の処置もいる。
>>668 レスどうもです。
頭悪くていまいち理解できてないんですが、受信バッファに
+----------
|ABCD・・・・
+----------
と入っていて
A=50バイト B=60バイト C=70バイト D=80バイト
だった場合、1500バイトでrecvかけたら
ABCDいっぺんに読めてしまうってことですよね?
>>669 >>668 じゃないけど、recvの第三引数に1500を指定するって事だよね?
それならABCD全部読めるかもしれないし、読めないかもしれない。
もしかしたら、Aの最初の5バイトしか読まないで返ってくるかもしれない。
完全に運の世界。
まあ受信バッファに本当にABCDが全部入ってるんなら全部1度に読めるけど、
プログラム側から受信バッファの内容を知る事はできないからやっぱり運。
だから普通は指定したバイト数読むまでrecvを何回も呼んできちんと読むような関数を作る。
>>669 面倒だから、fdopenしてストリーム入力使いなよ。
>>670 レスありがとうございます。
recvするたびにA、B・・・とデータの区切りごとにリターンしてくれる
ということでは無いんですね(そう都合よくはいかないか・・・)。
>>671 別の方法もあるということですか。
勉強してみます。ありがとうございました。
673 :
デフォルトの名無しさん :2008/01/03(木) 17:15:51
WindowsでIPヘルパを使っています。 複数のネットワークカードが刺さっている場合の取得順序について。 GetInterfaceInfo()での取得順序は何に依存するのでしょうか? バスの位置でしょうか?
select をつかって TCP 23ポートを開いてATコマンドを処理するプログラムを書こうとしている初心者ですが select の動作がいまいち理解できなくて難儀しています。 サーバープログラムの場合 listen したファイルディスクリプタを readfds 集合に入れて select を実行した場合、 select が戻った時に readfds に listen 用 FD があると、ちょうどクライアント側が connect したタイミングなので その場合accept してあげれば良い。のは大体分かりました。 で accept した FD を即座に select の readfds集合 と writefds集合 にいれているのですが、この場合 select が戻った時に readfds に accept した FD がある場合は、受信準備OKな状態で、この時に read すれば 受信データを得ることができて、 writefds に accept した FD がある場合は、送信準備ができた状態で、 write してあげればデータを送信ができるんでしょうか?この時、実際受信したデータがないか、送信するデータがな い場合もあると思うのですが、そういう場合は速やかに再度 select すれば問題ないですよね。。 このように理解しているのですが、何分うまくいかないのでどこか間違ってそうなのです。
selectのwritefdsというのは、「現在送信バッファに追記出来る状態ですよ」って のに近い。(まあ、connectの結果を見るのにも使えるけど。) 普通は、readfdsだけ仕掛けておいて、戻ってきたらrecv発行->受信処理。 なにか書きたくなったら、すぐsend。-1(EWOULDBLOCK)が戻ってきたら、 続きを送信するためにwritefdを仕掛けて待機。writefdが立てば続きを送信。
>>674 受信準備OKなものは、受信データがないってことはあんまりないと思うけど。
送信準備OKなものは、送信するものがなければ writefds から外すべき。
送信可能(送信バッファに空きがある)である限り、常に反応し続ける(selectが即座に返る)。
677 :
674 :2008/01/08(火) 20:58:49
なるほどサンクスです。write は失敗した時だけ writefds にいれとけばいいのですね。 ずっと select が返る状態だと、使う意味がなくなりますもんね。。
678 :
674 :2008/01/09(水) 18:52:35
連投すいません。 考えたのですが write( send ) はやりたい時に行い、失敗したら送れな かったデータをバッファに置き次回 select で writefds をセットする。。。 。とすると、write を行ったのが select を行っているスレッドであれば、se lect が戻った後に write なのでいいのですが、別スレッドで write すると select しているスレッドは受信データがない限り戻らないので、即座に続 き送信できませんよね。 select はタイムアウト設定できるようなので、タイムアウト1秒として、 送信するデータがあれば writefds をセットし select で戻れば送信として は駄目なんでしょうか、、そういうソース見たことありませんが。。
select使ってるのに、何でスレッドが分かれてるの? まー、IPC用にソケット1本確保して、同時にselectで見張る手もあるけど、 writeが競合するとか嫌な事態になりそうだなー。
適当なシグナルを発生させてやればEINTRで帰ってくるんじゃないかね だめだったら679のようにselect起こす用のsocketpairかpipeかなんかを作って一緒に待たせておけばいい writeはまぁmutexするしかないだろ
おお、シグナルやパイプを使えばうまくいきそうですね。select使ったコードを探していた時に見たことあります。 いろいろ教えてもらったいまなら、理解できそうです。。 いろいろ、ありがとうございました。
WinsockでWSAAsyncGetHostByName以外に非同期で 名前解決をする方法があれば教えて下さい。 コンソコールアプリからだと使いにくいです。。。
>>674 はtelnetプロトコル(rfc854)の存在を知っているのだろうか?
結構面倒なネゴシエーションが必要。
684 :
デフォルトの名無しさん :2008/01/12(土) 16:46:36
何が使いにくいん?
httpしか繋げたことないから難しく見えるんじゃね
>>682 スレッド起こして解決できたらイベントで通知
687 :
682 :2008/01/12(土) 18:07:52
>686 書き忘れていましたが複数のスレッドで同時に解決できるようにしたいんです。 でもgethostbynameだと同時に使えないから1つずつ解決することになって、 それはちょっと嫌だなあと。タイムアウトするまで次の解決ができないって状況は避けたい。
gethostbyname2_rとかなかったっけ?
たとえばadns使うとか。 NetBIOS系の名前解決はしてくれないけど
クライアント・サーバ間を共通鍵で暗号通信をしたいのですが, 通常のクライアント・サーバシステムにおいて,あるクライアントとの 共通鍵の関連付けはどのように行うのですか クライアントから通信を開始するとどの共通鍵で復号すれば良いかわからないと 思うのですが・・・
クライアント識別子みたいなのと鍵を1:1にしてサーバで保持しておけばどうかな?
使っていいのが共通鍵暗号のみなら 最初はユーザー名をそのまま送るしかないんじゃないの? パスワードは暗号化して
もしくは鍵からハッシュ値でも生成して最初の通信の時に付けておけば
694 :
690 :2008/01/14(月) 14:07:03
ありがとうございます
>>691 クライアントには,ユーザIDが与えられているので,それと関連付ける方法ができそうです.
ハッシュ値を使う方法もいけそうなので検討してみます.
695 :
デフォルトの名無しさん :2008/01/14(月) 17:00:13
鍵交換方式使えばいいと思うけどね まあ、どの程度の暗号強度を求めるのかで適当に決めればいいよ
ハッシュ関数って勝手に使ってライセンスって問題ないのかな? MD5とかSHA-1とか
アルゴリズム自体には無いけどライブラリは別なんで気をつけないといかん 嫌なら自分で書け
Javaならデフォでついてるけどな
700 :
674 :2008/01/15(火) 12:02:02
>>684 4-5年前 NetBSDの teldx だったかな、telnet サーバーのソースは見たことあります。
しかし、コードがトリッキーなのがはいってて理解不能でした。
teldx に限らず、while ループが何百行もつづいてたり、マクロがぐちゃぐちゃはいって
たりして読みずらい。。
>>694 OpenSSLは/etc/ssl/certsに証明書が置いてあるよ。
もちろん証明書の中には公開鍵が入ってる。
openssl dgstコマンドでハッシュつくって、
そのハッシュが名前になったシンボリックリンクが本体へ向けてある。
WindowsでもOpenSSLならC:\etc〜になるだけで同じ。
702 :
デフォルトの名無しさん :2008/01/15(火) 18:32:21
マルチスレッドで以下のような構成です。 ・UI スレッド(main スレッド) ・作業スレッド(Winsock1.1 初期化/後処理 + データの送受信) この場合はWinsockのデータベース関数をどちらのスレッドで使用するべきですか?
>>702 何がいいたいのかわからないのだけど…
>Winsockのデータベース関数
ってなにかな?
gethostby〜とか
netdb.h
>>702 今時 Winsock 1.1 もどうかと思うが、どっちにせよ Winsock
の初期化/後処理 (Cleanup のことかな?) を作業スレッドで
やるなら、Winsock 関連の処理は作業スレッドでやった方が
いいと思う。
新たに名前引き用スレッドプールを新設するのが好み。
結果のコンシューマもマルチスレッディドになってないと意味ないけどね。
709 :
デフォルトの名無しさん :2008/01/16(水) 16:51:22
作業スレッド内でWinsockの処理を行うとして、 データベース関数はWSAAsyncGetHostByName等、非同期を用いるべきでしょうか?
それは、君のやりたいこと次第だからなんとも言えないけど、 WSAAsyncGetHostByName() は、ウィンドハンドルを要するから 作業スレッドでは使いにくいよ。 ぶっちゃけ WSAAsyncGetHostByName() は、スレッド使わない 人向けだよ。
711 :
デフォルトの名無しさん :2008/01/19(土) 15:19:46
TCP最高や! UDPなんか最初からいらんかったんや!
712 :
デフォルトの名無しさん :2008/01/19(土) 22:03:37
WSAAsyncGetHostByName()を使わないとすると スレッド内でデータベース関数がブロッキングを起こさないようにするにはどうしたらいいですか?
別のスレッドを起動してそれにやらせる
ダイアログに貼付けたエディットの中の文字列をGetDlItemTextで取得し gethostbyname関数を使うとNULLが返されるんですが、 NULLが返される原因としては、どんなものがありますか?
プラットフォームがよくわからんけど、なんで errno とか GetLastError() とかを見ないんだ?
一番の原因として考えられるのは 渡した文字列を確認したりWSAGetLastErrorを見たりという簡単なことすら やろうとしない人間がコードを書いていること
ネットワークプログラミングとは関係ないし WindowsAPIとも関係ないな
718 :
デフォルトの名無しさん :2008/01/20(日) 23:45:31
WSAStartupはWinMain側でしか出来ませんか?
試した方が速くね?
試して出来ませんでした。
ということは出来ないってことだね 解決して何よりです。
ソケット通信について質問します。 サーバー win-XP JAVAアプリ クライアント Linux gccアプリ コネクション成立後に、クライアント側から close → open する場合、 close後にopenするまでの待ち時間はどのくらいとればいいのでしょうか?
別に待たなくて良い
>>723 サーバー側で時々クライアントのソケット断検出がうまくいかない時があったものですから。
アプリケーションの不具合みたいです。
すみませんでした。
生ソケ開いて Macアドレスと IPとポートでフィルタしようと 思うのですが、効率のいいアルゴリズム 知らないでしょうか?
受信がうまくいかないのですが、 //送信 char szBuffer[1024]; char lpFileName[1024] = "/case.html"; sprintf(szBuffer, "GET %s HTTP/1.0\r\n\r\n",lpFileName); nRet = send(Socket, szBuffer, (int)strlen(szBuffer), 0); if (nRet == SOCKET_ERROR) { SendMessage(GetDlgItem(pval->hWndMain,IDC_EDIT2),\ EM_REPLACESEL,0,(LPARAM)"sendに失敗"); closesocket(Socket); } //受信 while(1) { nRet = recv(Socket, szBuffer, sizeof(szBuffer), 0); if (nRet == SOCKET_ERROR) { SendMessage(GetDlgItem(pval->hWndMain,IDC_EDIT2),\ EM_REPLACESEL,0,(LPARAM)"recvに失敗"); closesocket(Socket); break; } if (nRet == 0) break; sprintf(szBuffer,"%s",szBuffer); SendMessage(GetDlgItem(pval->hWndMain,IDC_EDIT2),\ EM_REPLACESEL,0,(LPARAM)(LPCTSTR)szBuffer); }
> sprintf(szBuffer,"%s",szBuffer); ( ゚д゚) !?
729 :
デフォルトの名無しさん :2008/01/22(火) 01:17:46
動画にアクセスしたらzoomeのDQNは早い
70Mbpsぐらい出たよ インターネットなら
透過スピードに近いのではないだろうか?
http://www.lunascape.jp/community/ Lunascape Core Version 4.5.2.1 / ANSI
Operating System Version 6.0.6000
Internet Explorer Version 7.0.6000.
bitmask?よくわからん?
あきらめたほうがいいね
732 :
デフォルトの名無しさん :2008/01/22(火) 21:06:04
ソケットでの通信を行うときのバッファサイズについてなのですが、 イーサネットのフレームは最大1518バイトらしいので バッファは1600バイト程度取っておけばいいんでしょうか?
>>732 TCPのウィンドウバッファはもっと大きいよ。
どのくらい取っておくのが普通?
735 :
デフォルトの名無しさん :2008/01/23(水) 18:27:41
>>734 TCPとかイーサネットとかの仕様は考えなくて良い。
自分で設計したプロトコルに基づいてバッファを決めるのが普通。
どうせ、recvでまとめて受信したり、分割して受信したりするんだから。
736 :
デフォルトの名無しさん :2008/01/24(木) 14:50:24
質問す。 ソケット繋がった状態で、LANケーブル抜いて、すぐ差し直して、まだソケット繋がったまま。 何故切断されない?
TCPは送ったパケットが届かなくても何度か再試行するから、そのときに届けば問題なし
>>736 そもそも下のレイヤの信頼性を補うためのプロトコルがTCPだ…
739 :
736 :2008/01/24(木) 15:12:29
WindowsでLANケーブル抜くと断線扱いで
まさに
>>736 のときネットワークが落とされるんだが
これはどうしたらいいかね
741 :
736 :2008/01/24(木) 15:40:46
>>740 それは回線切断を検知したというか、
LANケーブルが抜けたことを検知した、ってことかな。
743 :
デフォルトの名無しさん :2008/01/27(日) 15:31:55
accept関数の宣言は /include/sys/socket.hでされてるのは分かったのですが externされてて中身がどこで表記されてるのかが分かりませんでした。 どこに表記されているか教えてもらえないでしょうか…。
UNIX系統なら、acceptの中身はシステムコール叩いてるだけだから、 カーネルに実体がある、といった方が良いのかな。
詳解TCP/IP Vol.2だと、uipc_syscalls.cを見てるね。
チャットプログラムを作ろうとしているんだけど 同時に複数のデータを送りたい場合はどういうやり方が常道なんだろう 具体的には発言者、発言内容、文字色のデータがあるとして 適当にカンマ区切りとかにして一回で送信するか それぞれで三回送信した方がいいのか
TCPなら3回に分けて送信したって区切りの代わりにはならんぞ 10バイトを3回送信しても30バイト一度に受信するかもしれんし1バイトずつ30回受信するかもしれんし 区切り文字でもいいけどデータサイズを前に付ける方がたぶん楽 カンマ区切りにするなら発言内容にカンマ含んでるときのことも忘れずに
isprint()な文字しか投稿不可能なんだろうから、 ヌル終端に決めといて、最大サイズ制限あり。 発言者\0発言内容\0文字色\0 が簡単と思う。 送られたデータサイズは疑う必要があるから、 (分散システムでは、完全性の仮定レベルをかなり低くする必要がある) データサイズが送られても、結局は同じ様なコードになる。 バッファ管理とか、タイムアウト処理とか。
749 :
デフォルトの名無しさん :2008/01/28(月) 12:53:24
質問なんですが、 select使って多重処理のサーバ作ってるのですが、 A、Bという二つのクライアントがサーバに繋がってるとして Aから送った文字列に対してのレスポンスをAだけでなくBにも返す時ってどうすればいいんですか? アドバイスだけでもお願いしますorz
AとBの両方に同じものをsendすれば?
ある装置で、クライアントで接続するTCPポートxxxxxと、サーバーで接続するTCPポートxxxxx + 1があって 装置から接続先に送るものを、クライアントとして接続したポートで送信し、接続先から装置に対して受信 するものをサーバーとして接続したポートで受信する仕様で通信しているのですが。 種類と発生タイミングの違う複数のデータに対して同じポートで送受信しないといけません。 送信するデータは応答を返すのですが、送信するポートと別のポートで応答を受信するような感じです。 糞仕様にしか思えないのですが、こういうのもありなんでしょうか?
SYNパケットはどんな目的で使われるものですか?
753 :
デフォルトの名無しさん :2008/01/28(月) 19:46:26
TCP3ウェイハンドシェイク
756 :
デフォルトの名無しさん :2008/01/28(月) 20:05:24
とんでもなく勘違いしているのかもしれんが Winsockってacceptで処理がとまりませんか? どうしてもこれが気に入らないのですが、どうにかならないですか?
ノンブロッキングにすれば止まらない
758 :
デフォルトの名無しさん :2008/01/28(月) 20:20:17
ありがとうございます!
非同期にしても止まらない
760 :
751 :2008/01/28(月) 21:40:17
装置A→装置Bに(Aから見た)送信専用ソケットと、受信専用ソケットを2つ開いてデータのやりとりをする形式についてです。 @が装置Aから装置Bに送信するデータ Aが装置Bから装置Aに送信するデータ 装置A 装置B ソケット1 ソケット2 ソケット1’ ソケット2’ | | @ | | | +------------>| | | | @の応答 | | |<-------------------------------+ | | | | | | A | | |<-------------------------------+ | | Aの応答 | | | +------------> | データはいろいろな形式があって、それを送受信用ソケットでまとめて送る感じです。 Telnet, FTP 等のサービスを送受信用ソケットでやりとりするみたいなものは、どうなんだろうかと。。
ごめんずれちゃった。。
頭悪いPLC屋とか相手だと、TCP2コネクションで送受信回線が〜 とか言い出すな。
俺は、これが気になる。 > Telnet, FTP 等のサービスを送受信用ソケットでやりとりする なんか、すごいこと考えてそうな予感... んなわけねーか。(w
Winsockを使ってSYNパケットを送信する事は可能ですか?
connect発行するんじゃなくて、生に「SYNだけ」送信する、 という話なら、おとなしくWinPCapとか入れて叩いた方がいいとおもう。
とりあえず効率や生産性を無視して動くものを作ってみろと言いたい
768 :
デフォルトの名無しさん :2008/01/29(火) 02:11:03
sendで任意のホストに文字列を送信したいんですが どうも上手くいきません。 アクセプトしたときのsockaddrinのIPとポートを弄るだけでは駄目なんでしょうか? どうすれば送れるのでしょうか
いいからソース出せや
770 :
デフォルトの名無しさん :2008/01/29(火) 03:03:22
とりあえずhost1から来た文をhost1,2に返すような感じのコードで あらかじめfrom2にhost2のIPポートを入れておいて socket() bind() listen() while(1) { switch(select()) case -1:エラー処理 case 0:タイムアウト default: accept( struct sockaddr * &from) recv() send() if(fromがhost1の情報だったら){ from = from2 send()
771 :
768 :2008/01/29(火) 03:09:06
>>769 あ・・途中でShift Enterで書き込んじゃいましたゴメンナサイorz
コード的には
>>770 のような感じです。
後はクライアントが打ち込んだ文字列をそのままオウム返しするような感じです。
これで動かすとhost1で例えばAAABBBと打ち込むと
host2には届かずに、host1だけにAAABBBと帰ってきます。
次にCCCDDDと打ち込んだ時に
host1だけにもう一度AAABBBが帰ってきます。
次にEEEFFFと打ち込んだときに
host1だけにCCCDDDが帰ってきます。
何かhost2に届かないばかりかワンテンポ遅れる+ダブって帰ってきてしまいます。
× 〜のような感じです × 基本を無視 × 環境を書かない
AAABBBが2度返ってくる時点で、どう見ても自分のコードのバグだろうに。 ところで、一番重要な、acceptの返り値はどうしてるんだい?
tteいうか、 >from = from2 >send() まさかこれで from2 のどこかのポートに何か送れると思ってる?
768は、TCPの「コネクション」というものについてもう一度考え直すように。 acceptの戻りのソケットは、そのIP:port専用で、from_addrを 書き換えたからと言ってもどうにもならない。
気になったんですが、 WinPCap等はどうやって作られているんですか?
777 :
760 :2008/01/29(火) 16:50:24
>>763 えーとPLC屋です。いわれてる通り、送信のみ、受信のみのコネクションをそれぞれもつ感じです。
Telnet, FTP というのは例えで、ネットワークの階層構造を考えたときに、トランスポート層のTCPとその上のサービスが
1:1じゃない実装になるのですが、ありなのかなと。
ありもなにも、TCP2回線つかって、TCPをもう一段建て増しに するような真似は止めとけとしか言いようがない。
>>776 たんにドライバに渡されるEthernetパケットのコピーを横取りしてるだけ。
TCPのTIME_WAIT状態に関してRFCでは2MSL時間とあり、OSの実装によって 30〜240 秒取られているのですが。 a.2MSLまたないで同じポートを使用した場合、ルーター等で貯めこんでいた以前のパ ケットを受信することで、シーケンスの順序がおかしくなりRSTフラグが飛び交う。 なのでTIME_WAITは必要? b.TIME_WAITはクライアント側に必要で、サーバー側は無視してよい。通信用とは別の Listen用ソケットを使用するとしても、通信用でTIME_WAITは無視してよい。 c.TIME_WAITと比較してごく短い間隔で接続を繰り返すアプリがあると、利用できないポ ートが増え続けいずれ通信できない状態になる。こういう時TIME_WAITは短くして良い? それともアプリが間違っている?
>>781 TIME_WAIT は TCP パケットの順序解決を保証するもの。
同一 IP/port 同士が一度コネクションを切り、新たに
コネクションを貼ったときにネットワーク内に同じシー
ケンスIDが登場しないことを保証している(新旧のパケッ
トが混ざらないことを保証している)。
要するに世界中のネットワークから通信に使ったパケッ
トが消えてなくなるのに 2MSL 待てばまぁいいんじゃね?
ということ。
たとえば、サーバ側で過去 2MSL 間に接続した相手の
IP/port のリストをローカルな port 毎に管理していて、
接続要求に来たクライアントの IP/port がリスト内に
無ければ 2MSL 待たずに接続して良い(似たような話が
RFC にあったはず)。
アプリケーション層でプロトコルの設計、送受信処理の仕方を 勉強したいのですが、おすすめの書籍やサイトはないでしょうか? やっぱり、RFCやオープンソースのコード読むのが一番?
ミドルウェアの解説本読んでみたら?
>>781 クライアントとかサーバとかじゃなくて、TIME_WAITは基本的に「先にcloseを発行」
したほうに生じる。んで、TIME_WAITが必要な理由は、教科書に書いてある通り。
a.TIME_WAITは必要だが、どの程度にするかは実装依存
b.最初に書いたとおり、クライアントかサーバは関係ない
c.アプリは間違っていない。TIME_WAIT時間を減らすか、HW資源を増やすかはアナタしだい
788 :
デフォルトの名無しさん :2008/01/31(木) 21:09:16
教えてください。 VC++ WinSock でサーバプログラムをしているのですが、複数クライアントからのデータ受信で難航しております。 仮に、サーバAがポート3000で待ちうけ状態の時、クライアントB及びCと接続、B、Cから同時にデータが送信された時、Aのrecvプロセスでデータがごちゃごちゃになります。 クライアントに対してのrecvはそれぞれスレッドで処理をしてるのですが、Bの受信イベントでCのデータも受信されてしまいます。 同一ポートでもacceptしたそれぞれのソケットで送受信できないのでしょうか? 考え方自体間違っていますか? お願いいたします。
>>788 >recvプロセスでデータがごちゃごちゃになります
ありえない動作だから、あなたのプログラムがバグってる。
acceptって書いてるし、たぶんTCPの話だよな?
ソースみせてみ。
>Bの受信イベントでCのデータも受信されてしまいます。 TCPだろ、そんな訳あるか。acceptで戻ってきたソケットは、 そのピア専用になるに決まってるだろ。 あるいはひょっとして電波が届いたけど、acceptの戻りを上書きして、 スレッドB.CでどっちもソケットCを待ってるとかいうオチじゃないだろうな。
791 :
788 :2008/01/31(木) 22:00:11
はいTCPです。ざっとですが、こんな感じです。 通信ソケットはクラス化しています。 CServerSock{ SOCKET m_Sock; recvfunc(); }; CServerSock SvSock[2]; AcceptFunc() { int cnt = 0; while( 1 ){ socket = accept(litensock,...); SvSock.m_Sock[cnt++] = socket; // B及びCのソケットを割り当て CreateThread(〜)で各m_Sock用のrecvスレッド(recvfunc)を生成。 } } CServerSock::recvfunc() { char buf[2048]; while( 1 ){ ret = recive( m_Sock, buf, len, 0 ); // このrecive後のbufの内容がB,Cごっちゃになります。 if( ret == 0 || ret == SOCKET_ERROR ) break; ::SendMessage( m_hWnd, m_wMsg, (WPARAM)len, (LPARAM)buf ); 親ウインドウへ通知 } } わかりずらいかもしれませんがよろしくお願いします。
> CServerSock SvSock[2]; > SvSock.m_Sock[cnt++] = socket; // B及びCのソケットを割り当て 普通、コンパイルエラーになるだろ。 (そもそも、private なメンバ変数 m_Sock にアクセスできないし...。) C++ じゃない、俺の知らない言語かも知れんが。
あれ? それってひょっとして、デバッガでブレークして確認したとかいわないよな?
794 :
788 :2008/01/31(木) 22:12:51
>>789 >>790 そうですよね。
基本的にBが送信A処理、Cが送信A処理の順番だときっちりBのスレッド、Cのスレッドで処理が行われるので・・・。
>>792 すいません。publicメンバです。書き忘れました。
>>793 ブレークとm_Sockの番号等で確認しましたが・・・。
ネタだろこいつら かまってほしいだけだよ
796 :
788 :2008/01/31(木) 22:59:26
>>795 残念ながらネタではないんですよ。
とりあえず、同一ポートでacceptした個々のSocketで送受信は問題なさそうなので、他でアホなことしてないかもう一度見直してみます。
すみません&ありがとうございました。
AcceptFuncのwhileでSvSock.m_Sock[cnt++] = socketのようにせず、 CServerSockのコンストラクタでsocketを受け取るようにしてみては? Socketの受け渡しが面倒だけど、オレはそうやって処理してる。
>>794 > すいません。publicメンバです。書き忘れました。
public でも、
> SvSock.m_Sock[cnt++] = socket; // B及びCのソケットを割り当て
は通らんだろ。(SvSock[cnt++].m_Sock = socket; ならわかるが。)
ネタじゃないなら、情報細切れに出さずに、ソースをそのまま載せるなり、
どっかにアップしろよ。
なにをもってごっちゃと判断してるの?
800 :
781 :2008/02/01(金) 10:59:33
>>782 ,785
なるほど、大変参考になりました。
ついでに、もう一つ質問・・
クライアント側で TIME-WAIT を発生させないようにする為、サーバー側は待ちうけ用の
listen ソケットを用意し、クライアント側から切断する時はサーバーに切断用の制御電文
を送信し、必ずサーバー側から Close を発行するのは大丈夫でしょうか?
待ちうけ用のlistenソケットを用意って、すでにあるacceptしてるやつとは別に?なんのために?
802 :
781 :2008/02/01(金) 12:37:36
えーと、listen で待つソケットと accept したソケットが同一の場合の実装もあると考えて、そうではないという意味で書きました。
そんなのあるのか?
今、UPnPを使いポートマッピングを行うプログラムを組んでいるんですが、 はじめはポートマッピングに成功するんですが、突然成功しなくなります。 それについて、どういった理由が挙げられるでしょうか。 どなたかご教授下さい。
>>791 >SvSock.m_Sock[cnt++] = socket; // B及びCのソケットを割り当て
cntはローカル変数なんだし、acceptされるたびに'SvSock.m_Sock[1]'
になるのでは?
あげ
ローカルだけど、while(1)でその関数抜けないならずっと生きてるんじゃないの。
Winsockでhtmlファイルを1024パイトずつ取得し、 calloc等により動的に記憶域を確保 そこに全て入れてからURLを抽出する、 という方法を考えているんですが、 何か、良い方法はありますか?
良い方法、というのは、たとえば、Perlでも使っとけ、みたいな話?
>>807 確かによく見たらbreak処理が無いな。
え。無限ループって事は配列オーバーしないかい?
あと、Acceptfunc()が呼ばれるタイミングもいまいちわかんないね。FD_ACCEPT直下?
それもスレッドから呼ばれるんじゃないの?知らないけど。 Main,Accept, 送受信スレッド連中、みたいな。
マルチスレッド使ったことなす;・ω・)
ポートマッピングに詳しい人。
>>804 をたのみます。
>>800 サーバからCloseを発行して、クライアント側ではrecvで0が返ったことを
確認してcloseすればクライアントはTIME_WAITには入らないから大丈夫。
ただし正常系はそれでいいが、例えばサーバが無応答になった場合など、
クライアントから切断せざるをえない場合も発生するよ。
切断用の電文は、
>>801 のいうように切断したい接続上でやりとりすれば
いいと俺も思う。バイナリを大量に転送中で中断が難しいような場合だと、
転送用の接続と、コマンド用の接続を分けるというのも確かにやるけど(FTPみたいに)。
>>804 理由はあまりに多すぎて、いちいちあげる気にならない。
パケットログか、ソースをアップしてくれ。
>>815 プログラムはほぼ
http://www.bosuke.mine.nu/neta/upnp.shtml を参考にしました。ってか、ここのサンプルでもあけられないです。
処理ではWANIPを取得する際に失敗するようです。
ちなみに、二重ルータなんですが、ルータのIPは192.168.xxx.1ではなかったです。
'1'の部分が百いくつだったはず…ここでミスってるんですかね?
ソースはサンプルプログラムのinvoke関数です。
XMLとかわかんないんであまりうまく調べられて無いような感じです。
>>816 >'1'の部分が百いくつだったはず…ここでミスってるんですかね?
UPnPは、IPアドレス情報も含めてプロトコル上でやり取りして、自動設定してくれる。
だから、ここは関係ない(はず)。
>>816 とりあえずinvoke関数の中のどこでエラーが返ってるかログしこむなりして、
調べれ。
二重ルータ?
>>817 なるほど
>>819 モデム(ルータ機能付き)>ルータ>★自分&他複数PC
________________>ルータ>複数PC
こんな感じです。
とりあえず、環境と離れるんで
invoke関数の調査は週明けにでもやります。
UPnPはエラーならエラーコードがわかるはず
>>820 ルータ(1)>ルータ(2)>設定を実行するPC
という環境であるとして、設定したいルータが「ルータ(1)」ならそもそも
できない可能性がある。UPnPはマルチキャストを使ってるのだが、
ルータ(2)がマルチキャストルータでないと、PCで発行した
マルチキャストパケットは、ルータ(2)を超えられない。
で、個人用の安価なルータがマルチキャストルータということは
まずない。
ルータ(2)がマルチキャストルータで、マルチキャストパケットが
ルータ(1)まで届いたとしても、同一ネットワークからじゃないと
UPnPのSOAPリクエストにたいして応答を返さないようなルータっ
ていうのは存在する。
でも、「出来るときと、出来ないときがある。」って書いてあるから、
ちがうのかもだが。
あーそれからルータをこえてマルチキャストパケットを届けたいなら、 IGMPメッセージを発行する必要がある。これはUDPソケットに対して、 IGMP_JOINなどをAPI経由で発行する。 やってるかもしれんが。
マルチキャストはルータ発見時しか使わないから、 そこをたとえば手動で設定すれば良いんじゃないかな。 ルータ1と2で同じポートを開けないとイケナイのがアレだけど。
でもなーんか、UPnP使う意味がない気がしてきたな。。。w
recvで1024ずつ一つのhtmlファイルを取得する場合 htmlファイル合計バイト分の記憶域を確保するためにはどうすればいいですかね?
最初に1024バイトのバッファを用意してそこに書いていって、足りなくなったら reallocすればいいやん。
C++なもので
>>827 それは
1 UPnPでルーターに穴をあける。
2 ルーターのWEB/IFをWAN側からアクセスする。
って事でいいのか?
>>831 DNSサーバアドレス書き換えて、フィッシングサイトにとばすとかもできるんじゃね。
>>833 残念ながら、UPnPにはDNSサーバーを設定するという機能はないのだよ。
char *buf; buf = (char *)calloc(1024,sizeof(char)); で記憶域を確保して、 確保した領域の大きさを変更する場合をどのように判断したらよいですかね?
>>836 ネットワークのスレじゃなくて、プログラミング初心者のとこで聞いてこいよ。
日本語でお願いします。
>>836 recvの返り値で読み込んだバイト数が分かるから、whileやforでカウントすれば?
まぁreallocとか時間かかるから、ある程度大きいバイト数を1ブロックとして、 ブロックごとで領域を確保していった方がいいと思う。いちいちrecvの返り値分だけreallocしていくよりはね。 HTMLファイルだけが対象ならアレだけど・・・。
ブロックごとに領域を確保していくっていうのがよくわかりません。
age
ブロックごとで領域を確保していく コードで示して下さるとありがたいのですが、 駄目ですかね?
Un*xのsendfileやWindowsのTransmitFileって効果が大きいですか? boost::asio使おうと思ったんだけどsocketの完全なラッパーなのでsendfileが使えなくてどうしようかなと
使われる環境で全然違うから、評価環境つくって測定しなきゃ意味ねー。
Webダウンローダーの仕組みってどうなってるんですか? htmlやjpg等の拡張子判別とか、html内のリンク抽出とか 重複I/O等使っているんでしょうか?
一行目と二行目の違いに愕然とした
もしかして wget の中身を知りたいの?
ちまちま数バイトずつ確保していくよりも、 ドーンと確保して足りなくなったらまたドーンと確保するって事だろ。 コードを示してもらうほどでもない。あと、スレチになりつつある。
>>844 ブロックごとでなくても良いから、一回自分で考えて作ってみたら
どうだろう?
>>851 に一票
正解を探し回るより、とりあえず動くものを作る方がいろいろ理解できるよ。
そもそも、最近のマシンだと、ちまちまメモリー確保してもそれなりに動くし。
てかメモリ確保くらいならサンプルコード腐るほど落ちてる。
854 :
デフォルトの名無しさん :2008/02/04(月) 21:44:58
こんにちは。 winsockでネットゲームを作っているのですが、 サーバーを介さないで4人のクライアント同士で通信し合いたい(peer to peer)場合、 各々が相手3人のクライアントのソケットを持ってる必要があるのですが、 どうやってクライアント側のソケットを取得するのでしょうか? (ホストのは取得出来ます)
TCP?UDP?
856 :
デフォルトの名無しさん :2008/02/04(月) 22:27:53
TCPです。 単純に4人共がlistenして全員が相手3人にconectし合えばいいのかな と思ったりしましたが、もっと良い方法はありますか?
普通のご家庭にはルータがあってNATの向こうにPCがあるもんだが その環境だと互いにtcpでつなぐのはしんどいぞ どういうのを想定?
>>856 別にそれでいいんじゃない?
>>857 ネットゲーム作ろうかと言う奴なんだから、バーチャルサーバとか
ぐらいは知ってるんじゃないかな。
バーチャルサーバ?
860 :
854 :2008/02/04(月) 23:15:42
マッチングサーバーを作ってそこで4人組み合わせて後はpeer to peerでと考えています。 接続時に指定するポート番号っていうのはホスト側のアプリケーション識別番号で クライアント側は自動的に空いてるポートが使用される。。。 という考え方で合っていますか? 4人共がlistenして全員が相手3人にconectし合う場合、 4人共がポート2000の同一番号でlistenしてても問題ないでしょうか?
グダグダ考えずに一台をサーバにすればいいじゃないか
>>860 問題ない。
て言うか、まずは二台でお互いにコネクション張って実験してみな。
863 :
854 :2008/02/05(火) 00:15:44
>>861 その通りなのですが、何故かそういう仕様になっているのです。
何のメリットがあるのか全くもって分かりません(泣
>>862 はい、やってみます。ありがとうございます。
1時間で仕様が決まったのかwww
仕様を作った馬鹿に質問するなり文句言えばいいのに
ハイブリッドP2Pって事か。 NAT越えが出来なくて泣いちゃいそうだな。 かくいう俺も出来ないわけだが。
>>863 リアルタイム系のゲームなら、いちいちサーバーを介してデータの
やり取りなんかしてられないので、P2P は別におかしくない。
まあ、それなら TCP と言うのがちょっと疑問だが。
P2Pだと同期制御が課題になってくるけどな
TCPってダメなの? 俺は、UDPは送信データの欠如があるとかであんまり信用して無いんだが。
両方つかえばいいんじゃないか? UDP -> リアルタイムに反映したいもの ( キー入力、キャラクターの移動ベクトル ) TCP -> 正確にやりとりしたいもの ( 同期取るPCからのデータとか )
>>869 TCPは信用しているということなら、
TCPスタックは信用しているって事なので、
アプリの要求から観て、信頼できるかどうかは、
中間層にかかっているのでは?
だからUDPで書いても、アプリに必要なレベルの信頼は保てる。
872 :
デフォルトの名無しさん :2008/02/07(木) 13:33:44
VS2005で Winsockを使っていてSD-BOTHが定義されていない、と出るのですが、 何でですかね?
SD-BOTHが定義されていないから
SD-BOTHが定義されていない、と出ないようにする
876 :
デフォルトの名無しさん :2008/02/07(木) 15:41:01
ソケットを閉じるときに いきなりclosesocketでも問題はないが、 shutdown(socket,SD_BOTH); とすることがある。 これは送信、受信ともに通信を切断する意味だったと思う。
shutdown(s, SHUT_WR);
>>814 いろいろと、ありがとうございます。
切断したい時はサーバーからCloseしてもらえば問題なく、また
相手がいなくなった時に自分から Close する場合は
1.相手応答ないので Close。
2.TIME_WAIT 状態になる。
3.TIME_WAIT 満了前に再接続する
4.local port +1 して(空きポートで)即 Connect する。
5.相手いないので Connect 失敗でエラーが返る。
6.エラーなので Close する。
と、接続状態から切断の遷移にならないので、TIME_WAITにはなりませんでした。
ということで、TIME_WAIT状態のソケットが溢れるとしたら、それは、
接続後に自分から切断しまた接続する動作をしてるって事ですね。
>>878 相手が存在しない場合、closeの発行ではFINの再送状態になる
わけだからTIME_WAIT状態にはならない。だがサーバがコマンド
に応答しない場合でも、FINに対しては(recvで0が返ったら)
close処理を行う場合、クライアントはTIME_WAIT状態に入る。
そこら辺まで行くと、ちゃんと書籍を横においてTCPの挙動理解
するようにしながら、プログラム造ったほうがいいと思うよ。
リチャード・スティーブンスのTCP/IPvol1一冊あればいい。
880 :
◆TCP/IPzk8E :2008/02/08(金) 23:44:57
test
素晴らしい
ほほう
883 :
デフォルトの名無しさん :2008/02/10(日) 07:51:52
質問です。 オンラインのアクションゲームを作りたいのですが、 プレイヤー間の同期を取る方法について詳しく知りたいです。
同期なんか取りません ネットワークの遅延は避けられません いかに結果の辻褄を合わせて上手く誤魔化すかに注力した方が良いかと思います
>>883 相対時間ではなく、絶対時間で動作させる。
886 :
デフォルトの名無しさん :2008/02/11(月) 00:25:12
>>884 推測航法?とかいうので移動を予測するとかいうのは聞いたことがあります。
>>885 クライアント側から「時刻XXXまでに○○へ移動」みたいなものを送る感じでしょうか。
時刻をサーバとクライアントで同期させる必要がありそうですね。
リアルタイム性のあるゲームに利用できるかもいまいちわかりませんが。
というか、クライアント→サーバ間でどのくらい時間かかるかためしたことありませんでした。。
pingとかではかってみます。
>>886 最終的にクライアントに戻すんだからクライアント→サーバー→クライアントの時間を考えた方が
一定時間ごとにサーバがスナップショット送って同期をとるのが基本 LAN限定にするならそうシビアになることもないけどな ちなみに演算はサーバ側で行うのが基本 同期とりやすいし、不正もある程度は防げる
889 :
デフォルトの名無しさん :2008/02/11(月) 13:18:35
失礼します。 現在、クライアント←→サーバー型のチャットを作ろうとしています。 ですがネットワークプログラミング自体が今回初めてで、 猫でもわかる〜の本を読んでいるのですが何から手をつければいいか分かりません。 どなたか基本的な作り方(?)、もしくは参考になるサイトをご存知の方がいましたら返答お願いいたします。 ちなみに言語はCで考えていますが、C++の方が比較的分かりやすい等あれば変更する予定です。
>>889 ソケットプログラミングでググレ
ほとんどは題材がチャットC/S
関数がわからなかったら関数名でググレ
>>889 チャットくらいなら、CとかじゃなくてPerl,Ruby,Pythonのようなスクリプト言語
がいいよ。
プログラムの初心者で、オブジェクト指向になじみがなければ、Perl使って
みるといいんじゃないかな。ブラウザ使ってのチャットならPerlでCGIを作る
方法を解説した本が一冊あったほうがいいんじゃない。
892 :
デフォルトの名無しさん :2008/02/11(月) 14:01:57
お早いレスサンクスです
>>890 すいません、素でググるの忘れてました・・・本当に大抵がチャットC/Sのものばかりのようで参考になります。
感謝です
>>891 最終的には3Dのネトゲを作ろうとしているので、Perlなんかで作ってしまうと色々問題が。
そのあたりの事もあるので、C言語で作ろうとしてまして・・・。
>>890 , 891
TCP のモデル知らずに組んで....
って落ちか?
client より先に server 落したら server 再起動時に
address in use とかエラー帰ってくるとか... ... ...
>>892 > 最終的には3Dのネトゲを作ろうとしているので、
> Perlなんかで作ってしまうと色々問題が。
まずは、ネットワークプログラミングに慣れろと言うことだと思うが。
C 言語がめちゃめちゃ得意でケアレスミスなんて俺には関係ネェとか
言うなら最初から C でもいいけどさ。
# そんな奴は、
>>889 みたいな質問はしないだろうし、
# 全角で Perl と書いたりもしないだろうな...。
896 :
デフォルトの名無しさん :2008/02/11(月) 16:16:38
>>895 あぁなるほど、そういう事でしたか・・・失礼しました。
以前多少かじった程度なのでこの際に少し弄ってみることにします。
897 :
デフォルトの名無しさん :2008/02/11(月) 16:25:57
898 :
デフォルトの名無しさん :2008/02/11(月) 16:31:28
| ____ | | | / / / _____/ / | / _/ |  ̄ _| \ | / / \ / ̄| ̄ヽ  ̄ ̄| ̄ ̄ /‐┬┐\ |. ‐┼‐ | / |  ̄ ̄| ̄ ̄ ││ │ __| ヽノ ノ │ _/___| し(_丿\ _____________ | | | |``'''‐- 、 | | l ∩ `、 | | | |│ | │ | | |│ ! | | _,.ィ| | _.ニ=´‐--、 | | ,、‐' ´_,.ィ| |>‐'' ⊃ ,) | | ( ⊂ -<! L.r '"´>''´ | | `''ー---‐''- 、.l>'''´ | | P l a y S t a t i o n | |_______________| __ __ __ / " / " =|= / / ヽ _フ ( ( (_ ( ヽ / o)
901 :
デフォルトの名無しさん :2008/02/12(火) 14:59:55
コンシューマ機でネトゲーつくったことある人いる?
ゲーム製作板行けよ
904 :
デフォルトの名無しさん :2008/02/15(金) 15:14:01
今、TCP転送実験をしているのですが、間違いの原因が分かる方おられませんか? 環境はVC.NET + SDKで勉強してます TCPでクライアントとサーバプログラムを作成し、ファイル転送実験を行っています。 1MBから100MBくらいのファイルはうまく転送することができるのですが、それ以上の大きなファイルになると、 微妙にファイルサイズが大きくなると言う現象が起きています。サーバはaccept関数をマルチプロセスで動かし、 recv関数もマルチプロセスで行っています。クライアントはsend関数をマルチプロセスで行っています ファイルサイズが大きくなるほど、ファイルサイズのズレも大きくなるような感じです。 原因の予想がつく方、助言お願いします
コード晒せよ
ファイルをテキストモードでオープンしていると、LFがくるたびにCR追加されるから サイズは増えるな。でも100MBまで1つもLFが無いのにそこから入るなんてそうそう無いしなあ やっぱコード見ないとわからん。
recvの戻り値(受信したバイト数)を確認してないとかいうオチ?
ネットワークプログラミングって何?
909 :
904 :2008/02/15(金) 18:25:45
>>907 するどいご指摘ありがとうございます。
大当たりです。確認を忘れてました。。
>>904 こーひーふいたじゃねーか・・・w
ギャグじゃないのだよね・・・w
不安すぎるから、送信したデータと受信したデータの内容が ちゃんと一致するか、テストしとけよw
ありえない、騙りじゃないのかよw
914 :
デフォルトの名無しさん :2008/02/15(金) 22:36:01
winsockでsend()でHTTPリクエスト送信してrecv()でデータを受け取るという単純なプログラムを書いています。 yahooや、google等は取得出来たのですが、exciteブログがどうしても取得できません。 エキサイトブログはどの人のブログを試してみても駄目でした。 以下のようなエラーメッセージが出ます。 HTTP/1.1 403 Access Forbidden Server: Microsoft-IIS/5.0 Date: Fri, 15 Feb 2008 13:28:38 GMT Content-Type: text/html --------------: --- <html><head><title>Directory Listing Denied</title></head> <body><h1>Directory Listing Denied</h1>This Virtual Directory does not allow contents to be listed.</body></html> InetSpyを見てHTTPヘッダを同じにしても駄目でした。 エラーメッセージからしてアクセスを拒否られているみたいなのですが解決方法ありますか?
取得しようとしてるURLは?
telnetでやってだめならあきらめれ
>>916 telnet でやったら出来たよ。
$ telnet <hogehoge>.exblog.jp 80
...
GET / HTTP/1.0
HTTP/1.1 404
Server: Microsoft-IIS/5.0
Date: Fri, 15 Feb 2008 14:24:02 GMT
Pragma: no-cache
P3P: CP="NOI DSP CURa ADMa DEVa TAIa OUR BUS IND UNI COM NAV INT"
Pragma: no-cache
Connection: Keep-Alive
Content-Length: 4030
Content-Type: text/html;charset=utf-8
Expires: Fri, 15 Feb 2008 14:24:03 GMT
Cache-control: no-cache
...
> HTTP/1.1 403 Access Forbidden http の勉強しろよ。 > Directory Listing Denied > This Virtual Directory does not allow contents to be listed. もしくは、英語の勉強な。 て言うか、telnet で試したら、 telnet ○○.exblog.jp 80 GET / HTTP/1.1 Host: ○○.exblog.jp で、普通に取得できたぞ。(Host を指定しないと、400 Bad Request で、 丁寧に Host を指定しろよゴラァといってくれるし。)
>919 それはHTTP/1.1でリクエスト出してるくせに 必須の筈のHostヘッダを落としたからだ。
921 :
914 :2008/02/15(金) 23:36:06
ありがとうございます。 でも、telnetって何ですか? ググって見たらwindowsに標準のソフト事だとあったけど良く分からない。 もうちょっと、調べてきます。
。。。
924 :
914 :2008/02/16(土) 00:21:20
結局良く分からなかった。 telnetってソフトですよね?Tera Termって言うの落としてみたけど使い方が分からず。 それを使えば、エキサイトブログのデータ取得できるかもしれないけど、 取得したデータを解析する場合プログラムに埋めないと駄目ですよね? その変が良く分からない・・・。
925 :
914 :2008/02/16(土) 00:22:11
と、書いたらレス来てた。 ちょっと読んできます。
>>924 ネットワークプログラミングをする時、テキスト系のプロトコル
(http, smtp, pop)をテストするのに実験用汎用クライアントとして
telnetが使えるという事。 もちろん最終的にはプログラムに組み込まなければ
ならないが、
>>914 のような問題はまずtelnetでちょこちょこと検証が
出来るので便利。
927 :
914 :2008/02/16(土) 02:04:05
なるほど、ありがとうございます。 自分はちと先を急ぎすぎたみたいですね・・・。 まず、telnetでの操作を覚えたいと思います。 ご迷惑お掛けしました。
928 :
デフォルトの名無しさん :2008/02/18(月) 16:02:50
はじめまして。質問をさせて下さい。
softbank出版の「WinSock2.0プログラミング」という本のP.45に
次のような記述があります。
・・・このポートという概念が在るおかげで、1つのマシンアドレスで
複数のソケットを使う事が可能となります。ソケットのフルアドレス
(sockaddr)は1つのIPアドレス、プロトコル、ポートから構成されます。
これらの3種類の情報が集まって、1つのソケットを一意に特定します。
同じマシン上にある2つのソケットを、同じプロトコルを使って
同じポートに関連付ける事は出来ません。それぞれが異なるプロトコルを
使うのであれば、同じポートに関連付ける事が出来ます。
そこで、お聞きしたいのですが、
>>788 以降の書き込みを見ると
この本の記述とは異なるようです。この本は間違っているのでしょうか?
788の人はたぶん何か勘違いしてるだけなので気にしなくていいかと
>>928 >同じマシン上にある2つのソケットを、同じプロトコルを使って
>同じポートに関連付ける事は出来ません。
アドレスが異なれば、同じプロトコルの同じポートでも関連付けられる。
・・・そういう話じゃないか。
933 :
932 :2008/02/18(月) 17:07:49
>>928 すまん、俺が勘違いしてた。
そこの「プロトコル」ってのはUDPとかTCPとかのレイヤの話か。
935 :
928 :2008/02/18(月) 18:54:57
本は正しいのでしょうか? 私の解釈だと、この本の通りであれば、TCPで繋ぐ時 サーバーが同時に接続可能なクライアントの数が ポートの数に縛られるような気がするのですが・・
http で あるサーバー 1 IP で ポートは 80 のみ なぜ同時に沢山アクセス出来ているんだと思う?
>同じマシン上にある2つのソケットを、同じプロトコルを使って >同じポートに関連付ける事は出来ません。 ここをちゃんと読めてない香具師は多い
「一つの(アドレス、プロトコル、ポートで一意)に複数のソケットを割り当てられない」 とは書いてあるが 「一つのソケットに複数のクライアントを繋げない」 とはどこにも書かれていない
イメージで、複数つながるときは複数Listenしてると思うんだろう。
>>935 ソケットは
・プロトコル
・自分のアドレス
・自分のポート
・相手のアドレス
・相手のポート
の組で区別されるので、自分側が同じアドレス・ポートでも相手側が異なれば異なる
サーバは1個のアドレス・ポートだけでいくつものクライアントを裁ける
ポート数には縛られない
・・・で合ってたっけ?ちょっと自信ない
便乗質問ですが 一つのソケットに繋げられるクライアント数の最大数は? あるいは何によって制限されますか? メモリ?OSが処理できるプロセス数?スレッド数?
>>935 つまり結局、
> サーバーが同時に接続可能なクライアントの数が
> ポートの数に縛られるような気がするのですが・・
その解釈でいいように思える。
unsigned short だから6万個くらいだっけ。
縛られるっつっても、現実問題としては充分だわな。
ダウト
>>941 openの方法にもよります
FAQにも書いてあるので見ておくとよいかと
また、ライセンスによっても制限があります
Win2000などは10までだったかな
>941 1つのソケットで繋げられるのは、1つのクライアントだけだろ?
>>944 の訂正
2000Proはサーバ用途のソフトは不可
XPProが10
VistaはEURAみたことないので知らん
>>928 > ソケットのフルアドレス
> (sockaddr)は1つのIPアドレス、プロトコル、ポートから構成されます。
> これらの3種類の情報が集まって、1つのソケットを一意に特定します。
ここは間違いだね。
これじゃacceptの引数のソケットと、
帰り値のソケットの違いを説明できない。
TCPの接続は
>>940 の組で識別するということが理解できてないようだ。
ただこれはAPIの本であって、プロトコルの本ではないから、
プロトコルについてはカマーやスティーブンスの本を読んで、
APIの解説はこの本を参照すれば?
もちろんMSDNも。
MSDNはどこに自分の欲しい情報があるか分かりにくいから、
こういう本を一読しておくとWinsock2全体を概観できていいよ。
リファレンスじゃなくて、解説本だからね。
>>945 「繋げる」の意味によるなあ。
TCP or UDPとか、マルチキャストとか。
色々と理解不十分なのがゴチャゴチャかいてるので、元質問者が混乱しそう
なのでいっておく。
>>940 と
>>947 が正解。
>>948 マルチキャストってソケット関係ないじゃん?
OSによるとは思うんですが、UnixドメインソケットとループバックIFでTCPではどっちが高速ですか?
ループバック
>>954 悩むなら両方に対応してオプションで選択できるようにするといいよ
「ウィンドウズだとプロセス作成が重い」という話をよく聞くのですが、 ウィンドウズでhttpサーバーを書く場合、どのような構成が適切だと思いますか? 1、1リクエスト=1プロセスを尊守する 2、いくつかのリクエスト(数十〜数百)をまとめて一つのプロセスで処理する 3、プロセスは1つ。1リクエスト=1スレッドで行う 4、プロセスは1つ。いくつかのリクエストをまとめて1スレッドで行う 5、プロセスもスレッドも1つ。すべてのリクエストを非同期で処理する
>>958 プロセス生成が重いと考えているのに、どうして1と2が選択肢になるのか。
7. 複数のスレッドですべてのリクエストを非同期処理する
7、プロセスチーズは雪印
雪印はあの事件以降買ってないわ
そうだね、雪印はちょっと怖いよね。 だから最近できたメグミルクってとこの買ってるよ。
967 :
932 :2008/02/20(水) 13:00:08
一方、IIS6ではTDIを叩いた。
TDIってそのうち非推奨になるって書いてあるけど、次のIISはどうするの?
IISはOSと癒着だから。 ミニポートドライバを挟み込むくらいは遣りかねない(w
>>967 マルチスレッドカーネルつかってても、組み込みなら1スレッドで非同期で全部やる
常識でしょ
>>972 なぜ常識なのかわかんね。
結果として1プロ1スレでやらざるを得ないことは多いけど。
スレッド増えるとコンテキストの切り替えで遅くなるからじゃない?
タイマによる切り替えだけじゃなくて、デバイスI/O待ちとかで積極的にdispatchするようにしとけば問題ない事が多い。
1タスクのスタック領域4kとってるとして、100個接続裁いて100スレッドになると 400kのメモリが必要。そして、さばく接続数に比例して使用するメモリがどんどん 増える。非常に無駄。
コンテキストスイッチに時間がかかるのも効率が悪い。 まぁ最近の携帯電話とかだと、鬼のようなスペックつんでるので、携帯電話 メーカーが作るのならいいのかもだけど。「うちのミドルウェアには、HTTP サーバもついてますよ!1接続、1スレッド必要ですが」とかいったら、 ゼッタイそのミドルウェアは採用されないな。
スレッドをプールしてもダメなん?
接続数が多くなる場合はIOCP使えってのは常道みたいだが。
Winsockの挙動について connect()するときに、以下の条件 1.プロトコルはTCP 2.HostAddressにDNS名を指定 3.DNS応答に複数IPが含まれている(DNSラウンドロビン等) において、DNS応答の1つ目のIPアドレスへの接続に失敗した場合、 接続再試行として、DNS応答の2つ目以降のIPアドレスへ接続を行ってくれる? それとも、接続試行を行うのは一つ目のIPアドレスに対してのみ? 知ってたら教えておくれやす。
おまいの使ってるconnect()とやらのパラメータには、何を渡すようになっているか知ってるか?
がびーーーん! 参考にしたMSDNのページをよく確認したら、 MFCのCAyncSocket。 逝ってきまつ… ;y=ー( ゚д゚)・∵. ターン \/| y |)
オレもその略号みるとそれ思い出すんだw ICPOだけどな
linuxでIOCP無いと思った windowsで実装されてるようなの。
IOCPは特許になっているので、 スケジューラ絡みの部分はLinuxに実装できないが、 aio_*を使えばほとんど同じことができる。
IOCPって特許になってたんだ。知らなかった。
組み込みのカスは死ねよ
日本のソフト産業でシェアあるのってほとんど組み込み系じゃねえか
>>989 すべてお膳立てされたPCでのプログラミングしかできないカスは死ねよ。
組込みと聞いて見てみたら、窓CEとかJavaなんてのは、よくある話。
組み込みと聞いて行ってみたら… ハードの事は何も分からないで仕切ってる奴がいて 1 octet を CHAR と書けとか 2 octet を WORD と書けとか 4 octet を LWORD と書けとか ... 言われるのもよくある話.
別に違和感ないけど。 むしろ、UCHAR, UWORD, ULWORD とかはいらんのか? と思ってしまう。
そういえば、これは本当に偶然だったんだけど azn っていう略称の動作があって、せっかくなので使用可否のフラグを char aznable; って書いたら上司に見つかって、2人でウヘラウヘラ笑いあった。
TCPでサイズが8kbくらいのデータを送ろうとするとへにゃるんですが、 TCP送信できるデータには最大サイズみたいなのはありますか? それとも、何か別の原因が考えられますか?
へにゃるって何だよ 具体的に何が起こったのか書け 1回のrecvで受け切れなかったとか、そういうことか?
999 :
デフォルトの名無しさん :2008/02/27(水) 15:11:08
どっちにしろ下の層で細かく分割されるんだ。 TCPやソケットはそういうのを考えなくていいように作られてるんだ。
へにゃりつつウヘラウヘラすればいいさ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。