したらば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


新着レスの表示


名前: E-mail(省略可)

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

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

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

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