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

このエントリーをはてなブックマークに追加
なるほど〜。そういうわけでしたか。
ありがとうございます。
>>920
そうか、プリアンブルもフレームのウチだったけか。

最小つーたのはイーサネットフレームではなくてIPの最小保証MTUのつもり。
今確かめたら576バイトのようだ。
925その1:04/03/21 19:10
クライアントから送られてきた文字列(CRLFで区切り)を受け取って
それを全クライアントに送信するプログラム(要するにチャットです)を
作っているのですが、大まかな感じは以下のとおりです。
言語はC#ですが、多少簡略化して書きます。
プログラムはコンソールアプリケーションです。

メインスレッド
while (true) {
 s = Console.ReadLine();
if (s == "quit")
  break;
 else {
  quit以外は読み捨て
 }
}

ネットワークスレッド

while (flag) {
 ブロックせずにクライアントの接続をaccept

 for (クライアントの数) {
  select
  s = recv
  メッセージ処理(s);//この中で、sの解釈および各クライアントへのsendを行う。
 }
}

926その2:04/03/21 19:11
このような感じのプログラムで、5、6人でチャット中に、突然
while(flag)内で固まってしまいました。そうなると、クライアントから
何を送っても反応がありません。

ところが不思議なことに、その状態で適当に何かを入力すると、
(つまりメインスレッド内のReadLine()内で処理が行われる?)
突然溜まっていたメッセージが怒涛の勢いで処理されて、再び
ネットワークスレッドが動き出します。
メインスレッドのReadLine()は、改行を打つまで戻ってこないメソッドですが、
単に1文字を打っただけでも、怒涛の勢いで動き出すので不思議です。
同じような現象に遭われた方、いらっしゃいますか?

要するに、一応各クライアントからのデータはサーバーに届いて
いるが処理されないままであり、何か文字を打ってReadLine()を
働かせた瞬間に、ネットワークのスレッドの固まりが解けて、届いていた
メッセージを怒涛の勢いで処理した感じなのです。
> for (クライアントの数) {
>  select

selectの使い方を知らない?
928その2:04/03/21 20:23
>>927
さっきそのことに気が付きました。selectは一気に判定したい
ソケットを放り込んむものですから、クライアント分回すのは
おかしい(というより非効率的)ですね。
929その2:04/03/21 20:24
修正してからしばらく様子を見てみます。
930デフォルトの名無しさん:04/03/21 21:36
激しくスレ違いかもしれませんが・・・
Winsock でサーバアプリを作った場合、Win2k Pro でも10クライアントまでなら
ライセンス的に問題ないですよね?
931デフォルトの名無しさん:04/03/21 21:47
HSPなんだが
hspsock.dllを使って
sockputでPOST送信したいのだが、CGIが標準入力としてうけとる情報は
どこに書き込めばいいんですか?
932デフォルトの名無しさん:04/03/21 21:49
>>931
「〜だ」と「〜です」のどちらかに統一してくれ。
まず日本語の使い方や礼儀というものを習って来た方がいいんじゃないでしょうか。
934デフォルトの名無しさん:04/03/21 21:54
hspsock.dllを使いてsockputでPOST送信しなむ。
CGIが標準入力としてうけとる情報は
いづくにか書き込めばよからむ。
>>930
そのライセンスってドメインやワークグループのサービスに関してだろ。
自前アプリに対しては治外法権だと思うが。
>>930
正直、気にした事がない。
プログラムというか、Windowsの利用規約とかに
詳しいスレに行って聞いた方がよさげな気もする。
>>935
Win2k 鯖の場合は、Windows 認証を利用しないアプリは治外法権なのですが。。
Apacheに対するMSKKの見解でこういうのがあります。
http://www.apache.jp/misc/windows.html

(1)Apacheは「インターネットの情報サービス」であるため、 EULAにおける
 「インターネット情報サービス」に関する規定が適用される

(2)ApacheはEULAの「サーバーソフトウェア」に該当するため、
 『サーバーソフトウェアとしては使用できない』旨の記述がある
 OS(Windows 2000 Professional等)では使用できない

(3)EULAに『サーバーソフトウェアとしては使用できない』旨の記述のない
 OS(Windows XP Professional等)でのApacheの使用は問題ないが、
 「最大接続数」の制限によって端末10台以内からの利用に限られる。

(4)「インターネットの情報サービス」、「ファイルとプリンタの共有サービス」、
 「リモートアクセス」サービスのいずれかの機能を利用するソフトウェア の
 使用には同様の制限が適用される。

(1)(3)(4)項は良いとして、(2)項は Win2k pro の EULA の何処にも書いて無いんですけどね。
>>936
それらしいスレが見つからないのです。
GPLのはあるけど。
Linux使え!
>>930
ここで少しだけど議論の対象になってる
http://pc2.2ch.net/test/read.cgi/gamedev/1072515100/
IISをインターネット情報サービスと訳すからおかしくなるんだ。IISのままにしとけ
942925,926:04/03/21 23:32
取り合えず暫定的に、selectをやめて単数socketのチェックであるPollを
使ってみたんですが、状況は変わりません。
メインスレッドでReadLine()を刺激してやる(何かしら文字を入れる)と
突然動き出すのが意味不明ですが、気長に見てますのでもしご存知の
方がいらっしゃれば教えて下さい。
>>942
ソース全部晒せ。それが早いぞ。
>>942
根本的にselect()の使い方を間違ってるような気がしますが。
Winsockのサンプルですが参考にしてみてください。
http://www.kt.rim.or.jp/~ksk/wskfaq-ja/examples/basics/select-server.cpp
945930:04/03/21 23:46
Windowsのユーザ認証機構を使わない独自のサーバだと
接続制限を受けないと解釈するのが正しいようですね。

外 資 系 企 業 の 日 本 法 人 は 何 処 も ア フ ォ ば か り

これも正しい。w
946925,926:04/03/21 23:47
>>943
>>944
selectをソケットごとにやるというのは明らかに本来の使い方ではないけども
それをやったとしても、非効率的だがそれがおかしい動作の原因にはならない
というのは甘いでしょうか。ただ、本来の使い方からはおかしい以上、もちろんそういう
やり方はやめるつもりです。

いずれにしても頂いたサンプルソースを見させていただいて、問題点を
もう少し切り分けてみて頑張ってみたいと思います。ありがとうございます。
>>946
どこで固まってるかは調べたの?
select(), recv() ?
>>946
select() をソケットごとにやるのと recv() でブロックするのは同じでは?
つまり、select() するのは意味なーいじゃん。
949930:04/03/21 23:51
と、いうことで Win2k Pro + オレオレ鯖 + MSDE で接続無制限、と。。
>925
チャットプログラムなんだよな。

ネットワークスレッドでのメッセージ処理のConsole.Print(だったけか)
あたりがメインスレッドのReadLineとケンカしてるんでねーの。
951925,926:04/03/22 00:01
>>947-948
>>925からネットワーク担当のスレッドだけ持ってきたんですが、

while (flag) {
 ブロックせずにクライアントの接続をaccept

 for (クライアントの数) {
  select(そのクライアント) ←今は取り合えずPollに変えました。
  s = recv(そのクライアント)
  メッセージ処理(s);//この中で、受け取ったメッセージを解釈し、全クライアントへメッセージをsendしています。
  Console.WriteLine(処理したメッセージ)
 }
Sleep(1);
}

このスレッド(whileループ内)のどこかで固まっていることは分かります。それでよく調べてみると、
メッセージ処理関数の中で処理されたメッセージは各クライアントにsendされているようです。
(「全ての」クライアントに正常にsendされたかはこれからの調査になるのですが…)。しかし
処理したメッセージを表示するはずの、次行のWriteLine()が動いていないので、もしかしたら
どれかのクライアントへのsendで停止している可能性があります。
でも、不思議なのはsendで停まっているのは理解できるのですが、何故その場合に、適当な
キーをポチッと押して、>>925のメインスレッドないのGetLine()を刺激すると、停止しているのが
何ごともなかったかのように動き出すのか、という部分なのです。
なんか間違えて標準入力の番号でselectしちゃってるとか
953925,926:04/03/22 00:04
>>950
ありがとうございます。私もその線は怪しいと思っています。
ReadLine()で待ちながら別スレッドで、様々なタイミングでWriteLine()が
何回も呼ばれるので、ちょっと不安があります。
ネットワークとは全く関係ないバグかもしれませんので、このスレで相談するのも
ちょっと気が引けたんですが・・・。ただ、メインスレッドでReadLine()を待ちながら、
ネットワーク担当スレッドで適宜、WriteLine()はしていますが、クライアントごとに
スレッドを作っているわけではないので、WriteLine()に関しては、同時に呼び出される
ことはなく、WriteLine()同士が被ることはありません。
954925,926:04/03/22 00:06
>>952
C#(Winsock 2.0のラッパーでしょうか)で作成しているので、
標準入力のselectはできないんです。
こういうバグが一番難しいですね。なんせ数時間に1回ぐらいしか
起こらないので…。
レスをいっぱい使用してしまいすんません。
どこで止まってるかをまず完全に見極めないと。
よく分からんけどWriteLine()は動いてるけどフラッシュされてないので
動いてないように見えてる、って可能性もあるし。
956925,926:04/03/22 00:29
ネットワークスレッドの実行関数Runに、staticキーワードが付いていないことに気付きました。
とても嫌な予感がしてきました……。
957925,926:04/03/22 00:43
関係無かったようです。
日記スレじゃないんだけど。
UDP socket の recvfrom() で、dest-addrがわからないのは、
意図的な理由があるのでしょうか?
>>959
単に(4BSDの頃の)最初の設計がそうだっただけ。

確かにdstのsockaddrも欲しい時もあるが、dst別に分けたいなら
bindする時にアドレス別にbindしてsocketを必要なだけ作るのがセオリーだな。
>>959
宛先は自分だから知ってるはずだろ。
忘れたらgetsockname(2)でも使えや。

>>959
?
962((≡゜♀゜≡)):04/03/23 11:19
>>961
自分に割り当てられているアドレスは一つとは限らないからでは。
960が言っているのはINADDR_ANYを使わないで・・・ということだと思う。
>>959
IP_RECVDSTADDR オプションを使えば、dest-addr が分かるよ。

IP_RECVDSTADDR オプションが有効になっている場合、
recvfrom(2) の完了時に帰されるアドレス構造体が、src-addr
ではなく、dest-addr になる。

>>960
どんなセオリーだよ、それ。dest-addr が欲しけりゃ
IP_RECVDSTADDR 使うだろ、ふつー。
964839のpptの中の人:04/03/23 16:41
さらされ記念ぱぴこ。
965デフォルトの名無しさん:04/03/23 17:36
>>963
両方ほしい場合はどうするの?
俺は>>960ではないが、
IP_RECVDSTADDR なんてオプションしらなくて、
IP別に受信するならIP毎にソケット作ればいいやん?
と思いついちゃった俺は、無知な上にふつーじゃないんだな… orz
まあ963はネタなわけだが。
IP_RECVDSTADDR ってIPv4でも使えるの?
>>968
使える。
>>962
わーい、ドラえもんだー
971デフォルトの名無しさん:04/03/25 00:02
メッセージキューを使用して
プロセス間通信のプログラミングを行いたいのですが
別サーバ間でのプロセス間通信は可能なのでしょうか?

このスレで良いのかどうかわかりませんが・・・
スレ違いの場合は誘導していただけると有難いです。
>>971
SVR IPC に多くを求めてはいけません。
おとなしく、socket などを使いましょう。