したらばTOP ■掲示板に戻る■ 全部 1-100 最新50 | メール | |

「C#、VB2005 でSocket通信」について

1コーヒーブレイク:2009/02/26(木) 11:06:29
はじめまして、コーヒーブレイクといいます。

VB2005でのSocket通信が理解出来ず、本やらマイクロソフトのマイグレーションTips
やら各HPやらいろいろ見たり自分で試行錯誤したりしたのですが、
いまだ完成しない状態でこちらのサイトを見つけました。

コメントもいっぱい書いていただいているので非常にわかりやすくてほんとうに
ほんとうに助かっています(どこの情報もシングルスレッドでの接続待機で記載
されているものばかりでしたので)。
是非一通り完成させたいと考えているのですが、何点か質問があります。

 質問1.自分でも一からコーディングしつつ勉強もしているのですが、
     ダウンロードさせていただいたそのままのソースでもデバッグを
     実行すると終了出来ていないみたいです。
     うまく終了する手法を教えていただけると助かります。
     ※ちなみにダウンロードしたままの状態でFormClosingの前の
      From名のみ修正しています。

     [手順]
       サーバを選択しStartした後にStopを押して×ボタンを押す。
       あるいはStartした後に×ボタンを押す。


 質問2.最終的には1(サーバ)対n(クライアント)をやりたいと
     思っています。
     どの部分を修正すれば良いでしょうか?


自分なりにやってはみたのですが、完全に手詰まりになってしまった
ので書かせていただきました。
お手数おかけして申し訳ないのですが、回答よろしくお願いいたします。

2igoten:2009/02/26(木) 12:44:25
どうもigotenです。

Server終了の件:
サーバーの終了はStopボタンを押すとCloseServer()メソドが呼ばれて、
更にCloseServer()メソドが呼ばれますが、この中でエラーが発生すると
言うことでしょうか?
もしCloseServer()の中の
server.Close() と
threadServer.Abort() が
正常に行われれば、正常に終了すると思われます。
>実行すると終了出来ていないみたいです。
何故その様に思われるかを教えてください。

1(サーバ)対n(クライアント)の件:
VB6では簡単に出来ましたが、VB2005はかなり難しいプログラムになりそうです。
私もやってみていないので推測ですが、
ServerListen()の中の
server(i) = listener.AcceptTcpClient()
のserverを配列にして、別スレッドで常時ポーリングして
新しい接続要求が来たら新しいserverを作り、
Dim stream(i) As NetworkStream = server.GetStream()
これも新しいstreamを作りポーリングでstreamを読み込む事になると思います。

3コーヒーブレイク:2009/02/26(木) 18:34:06
igotenさん、早速の回答ありがとうございます。

>>実行すると終了出来ていないみたいです。
>何故その様に思われるかを教えてください。
Stopボタンを押した後×ボタンを押した時にVisual Studioの「デバッグの停止」
ボタンが有効になっているからです。
停止同様「すべて中断」も有効なので中断してみるとセカンドスレッド内の
server = listener.AcceptTcpClient()
で止まっているようです。


1(サーバ)対n(クライアント)の件:
  igotenさんがおっしゃっていること頭の中のイメージだけですが、
  理解出来ます。
  理解出来るようになっているだけでも少しは進歩してるのかな?
  とにかく、終了のところがきちんと動作した段階でこの問題について
  igotenさんのアドバイスを元にがんばってみようと思います。

4igoten:2009/02/26(木) 21:17:44
Server終了の件:
よく見ると、listener.Stop()が抜けています。
CloseServer()メソドの先頭に
listener.Stop()
の一行を入れて下さい。
大変失礼しました。

1(サーバ)対n(クライアント)の件:
は非同期で行った方がよいと思われます。
どこかに記述がありましたので、明日までに探しておきます。

5igoten:2009/02/27(金) 09:01:43
私が見たのはこの本でした
「プログラミングC# 第5版 」
http://www.oreilly.co.jp/books/9784873113968/
ここの「複数コネクションの扱い」と言う箇所です。
ここに非常に良く書かれています。
私も時間が有れば作って見たいと思うのですが。
ソースはここからダウンロード出来
http://www.oreilly.co.jp/books/4873112648
「AsynchNetworkServer」
の項目が「複数コネクションの扱い」のサンプルコードとなっています。

6コーヒーブレイク:2009/02/27(金) 10:49:13
igotenさんへ

>CloseServer()メソドの先頭に
>listener.Stop()
>の一行を入れて下さい。

下記コードをcloseServerの中の先頭に入れてみました。
If listener IsNot Nothing Then
listener.Stop()
End If

そうすると例外エラーが処理出来ていないようでしたので
ServerListen全体を下記コードでくくる形にしてみました。
Try
Catch e As ThreadAbortException
Return
Catch ex As Exception
Return
End Try

結果イミディエイト ウィンドウに下記内容が表示されますが
Catch e As ThreadAbortExceptionのReturnを通って終了しているようです。

'System.Threading.ThreadAbortException' の初回例外が System.dll で発生しました。
'System.Threading.ThreadAbortException' の初回例外が WinsocVb.exe で発生しました。

こんな感じですが、あっていますでしょうか?


「AsynchNetworkServer」
C#の知識が全くないのですが、clientHandlerを複製してやっているようですね。
igotenさんのソースに置き換えるならば、igotenさんが最初に書いていただいた
ようにServerListenで受信するのではなく、接続要求を受けたらスレッドを生成
し別スレッドにて処理するようにすれば実現出来そうですね。

7igoten:2009/02/27(金) 14:29:24
終了は結構厄介ですね。
TcpListener のCloseまで時間がかかる為、一度閉じたスレッドが
再び立ち上がってしまう感じですかね。

'//サーバーのクローズ
Private Sub CloseServer()
listener.Stop()
listener = Nothing
この2行を入れて

Private Sub ServerListen()
If server Is Nothing Then
Return
End If
この処理の頭で listenerが無い場合は強制的に排除したら
良いと思われます。
コーヒーブレイクさんのコードでも良いと思いますが、上のコードだとエラーが
報告されません。

「AsynchNetworkServer」
VB2005でしたね、非同期処理に関しては興味が有りますので
時間が空いた時に試して出来ればコードをUpします。

8コーヒーブレイク:2009/02/27(金) 15:36:34
igotenさんへ
  教えていただいたコードを追加したところ見事にエラーもなく終了出来ました。
  エラーが出るより出ない方が絶対良いですね。

>VB2005でしたね、非同期処理に関しては興味が有りますので
>時間が空いた時に試して出来ればコードをUpします。
期待しています。
自分でも教えていただいたコードをベースに試行錯誤してみたいと思います。

こんなド素人に最後まで丁寧におつきあいいただけたこと、ほんとうに
感謝しています。
他のコンテンツも非常に魅力的なものばかりで時間があれば随時見ていきたい
と思っています。
socketの非同期も含め、また何かありましたら今後ともよろしくお願い
いたします。
ほんとうにありがとうございました。 m(_ _)m

9igoten:2009/03/12(木) 18:04:56
とりあえず複数接続非同期のプログラムは出来ましたのでUpしました。
不具合が有ると思いますが追々詰めていきます。
http://www.geocities.jp/hatanero/socket2.html

10コーヒーブレイク:2009/03/16(月) 19:18:07
igotenさん、先日はお世話になりました。

複数接続非同期のアップお疲れ様です。
じっくり腰を据えて読ませていただこうと思ってます。

11いくいく:2009/04/24(金) 02:02:11
複数接続非同期のソース拝見しました。
NetworkStream.BeginRead
のコールバックメソッドは、非同期IO用の別スレッド上で、
読み込みが開始した時点で呼ばれるのでは?

12igoten:2009/04/24(金) 08:34:01
NetworkStream.BeginReadのコールバックメソッドはBeginRead の完了時に実行されます。
http://msdn.microsoft.com/ja-jp/library/system.net.sockets.networkstream.beginread(VS.80).aspx

問題はNetworkStream.BeginReadの完了時は何時かということですが、
「非同期IO用の別スレッド上で、読み込みが開始した時点で呼ばれるのでは?」
でないことだけは確かです。
読み込みを開始した時点、読み込みが開始された時点?
があるパケットを受信した時点ということであればそうかもしれません。

私の説明は本文の方は「受信が終了すると」となっていて、コードの中の説明は「読み込み完了時」と
なっています。
あるパケットの受信が終了した時点、あるパケットの読み込みが完了した時と言うようなつもりで
書いたのですが、それも正しくないかもしれません。
正しくは「NetworkStreamが読み込み終了と判断した時」といことですか。
掘り下げると、TCP/IPのドライバーが一区切りのデータを受信したとNetworkStreamに報告
した時ということでしょうか。

13いくいく:2009/04/25(土) 00:01:35
〇どのスレッドでコールバックが実行されるか

英文のnetworkstream.endreadのページにbeginreadの説明がありますが、
callback method executes in a separate thread and is called by the system after BeginRead returns
とあります。
スレッドのハッシュコードを調べましたが、呼び出し元と違うスレッドでした。
コールバックメソッドという名前なので元のスレッドに戻るような
印象を受けますが、元ではなく別のスレッドだと思います。
サイトの図ではコールバックをサーバー用スレッド上に書かれてましたが、
誤解を招くのではないでしょうか。

〇いつ実行されるか

クライアントが接続してまだデータを送信していない時、
非同期IO用のスレッドはbeginreadのところで止まって、
コールバックはさらに別スレッドで動いているようです。
非同期IOスレッドはnetworkストリームが利用可能になるかエラーになるまで
ブロックし、コールバック用スレッドはbeginreadの呼び出しが完了した
時点で別スレッドで動きだすということではないでしょうか。
OnReadCompleteというメソッド名はよくないのではないでしょうか。

14igoten:2009/04/25(土) 11:07:58
 説明を原文で読むことは良いことですね。(^^
callback method executes in a separate thread and is called by the system after BeginRead retuns
「コールバックメソドは別のスレッドで実行され、BeginReadが戻った時に呼ばれます。」と言うことですね。
クライアントから接続要求があると、メインフォームは新しいClientHandlerのクラスのインスタンスを
作成して、StartRead()を実行する、StartRead()の中身はnetworkStream.BeginRead()でこの処理は
別スレッドで行われ、終了時には引数で渡したcallbackReadが呼ばれる。
callbackReadはClientHandlerクラスのコンストラクタで作成した下のメソドである。
callbackRead = new AsyncCallback(this.OnReadComplete)
>サイトの図ではコールバックをサーバー用スレッド上に書かれてましたが、
図はすべてサーバー上のスレッドです。
概念図に突っ込まれるとちょっとドキドキしますが、この場合は特に不具合は無いと思います。
>非同期IO用のスレッドはbeginreadのところで止まって、
これはその通りです。
>コールバックはさらに別スレッドで動いているようです。
この意味がわかりません。
>コールバック用スレッドはbeginreadの呼び出しが完了した
>時点で別スレッドで動きだすということではないでしょうか。
すみませんこの意味もわかりません。
>OnReadCompleteというメソッド名はよくないのではないでしょうか
名前ですか^^; 結構適当です、ただしこのOnReadComplete名ですが、最後に書きましたがオライリー・ジャパンの
「プログラミング C#」と同じ名前にしてます、私にはこんな名前を付けるセンスはありません。

15いくいく:2009/04/25(土) 13:57:26
丁寧にお答えいただき、ありがとうございます。
コールバックがさらに別スレッドで動くというのは、
呼び出し元スレッドを[beginread戻り値].waitone()を使ってブロックした際、
コールバックメソッドの終了を待つことができなかったからです。
呼び出し元と、非同期IOと、コールバックはすべて別の
スレッドなのかなあと疑問を持ちました。

コールバックの動き出すタイミングについては、igotenさんの
おっしゃった
「TCP/IPのドライバーが一区切りのデータを受信したとNetworkStreamに報告
した時」というのどうやって確認すればいいのかわからなかったのですが、
そちらのほうが正しいと思います。
ということは、その時点が原文のいうafter BeginRead returns
なのでしょうか。混乱してしまってすみません。

16igoten:2009/04/25(土) 15:37:44
コールバックから呼ばれるOnReadCompleteメソドはクライアントが接続してきた時に
作成したクライアント毎のClientHandlerクラスのインスタンスで、これはメインスレッドとは別の
a separate thread です。
これを呼び出すメソドは上記のClientHandlerクラスのインスタンスのStartReadで作成された
別のスレッドですね。
正確に言うと、「is called by the system」という事なので、systemが呼び出すのでしょう。
WaitOne(Mutex)に関しては試してないのでわかりません。

>...一区切りのデータを受信したと...
これは私の勝手な想像で正確なところはわかりません。

>その時点が原文のいうafter BeginRead returnsなのでしょうか
そのとおりだと思います。
after BeginRead returnsの時にcallbackRead = new AsyncCallback(this.OnReadComplete)
で登録されたOnReadCompleteのアドレスがis called されるという事でしょう。

17バーバリー バッグ 一覧:2012/11/01(木) 00:14:30
こんにちは、またブログ覗かせていただきました。また、遊びに来ま〜す。よろしくお願いします
バーバリー バッグ 一覧 http://www.burberryfactory.com/バーバリー-バッグ-c-24.html

18モンクレール ダウン店舗:2012/11/16(金) 06:13:08
今日は よろしくお願いしますね^^すごいですね^^
モンクレール ダウン店舗 http://www.middleeastmanagers.com/

19air max skyline:2013/05/29(水) 20:34:45
This webpage has so a lot great details on it, I verify on it everyday. I wish other websites spent as a lot work as this one does generating data legible to readers like myself. I recommend this write-up to all of my facebook friends. This webpage will make some massive passive profit I’m positive. I hope my site does along with this one, it refers to jewelry consumers houston. air max skyline http://air-max-skyline2.webnode.fr/

20フェラガモサンダル:2013/06/25(火) 18:51:02
しっかりとした作りで、デザイン性にも優れていたのですが、何せ重くて結局手放すことになりました。 フェラガモサンダル http://ferragamo.atukan.com/

21ルイヴィトン アウトレット:2013/07/06(土) 05:38:57
匿名なのに、私には誰だか分かる・・・(^_^;)ありがとう。。。 ルイヴィトン アウトレット http://www.kfsmtv.net/Vuitton/

22モンクレール:2013/10/09(水) 00:37:34
超人気 モンクレール ダウン、専門店 モンクレール 新作、モンクレール 伊勢丹 熱い販売 、モンクレール 池袋特価【最大80%OFF】、モン モンクレール http://moncler-outlet.jp/

23クロエ バッグ:2013/10/22(火) 16:18:07
Ahaa, its good conversation about this article here at this weblog, I have read all that, so at this time me also commenting here.
クロエ バッグ http://www.myindyareahome.com/

24日本最高級激安高品質スーパーコピーN級品:2019/04/11(木) 02:40:56
大SALEが開催中

◆ブラントコピー人気通販店の大SALEが開催中◆
弊社は長年の豊富な経験と実績を持ち、
ブラントブランドコピー品の完壁な品質を維持するために、
一流の素材を選択し、精巧な作り方でまるで本物のようなな製品を造ります。
また、お客様のご注文商品を責任を持ってお届けいたします。
シャネルコピー、ルイヴィトンブランドコピー、プラダコピー、ボッテガ・ヴェネタコピーやグッチコピー


新着レスの表示


名前: E-mail(省略可)

※書き込む際の注意事項はこちら

※画像アップローダーはこちら

(画像を表示できるのは「画像リンクのサムネイル表示」がオンの掲示板に限ります)

掲示板管理者へ連絡 無料レンタル掲示板