
はじめまして。VB.NETで質問があります。内容は、(スレッドと)ソケットを使った「非同期」通信についてです。
マイクロソフトのページからサンプルコードをコピーして、二行のプロジェクトを作成し以下の二つのコードを追加したんですけど…(ipの指定は、GetHostNameを使っています。)
プロジェクト1:非同期クライアント ソケットの例
Button1_Click
AsynchronousClient.Main()
プロジェクト2:非同期サーバー ソケットの例
Button1_Click
AsynchronousSocketListener.Main()
マイクロソフトのページ(ソケットのコード例)
→ http://www.microsoft.com/japan/msdn/library/defa …
プロジェクト2のフォームが固まってしまいます。
(Waiting for a connection...を出力ウィンドウに表示したままになってしまいます。)
暫定策として、Shellを使って、サーバー(プロジェクト2のexe)を起動してみたのでが、それでも固まってしまいました。
3日間ぐらいかけてネットで検索とMSDN見たけど、分かりませんでした。キーワードは、以下の通り…
「マイクロソフト .NET スレッド フリーズ サンプルコード 非同期 マルチ select -sql」
Select フックなどの言葉も関係があるようなのですがよく分かりません。
ただ、フォーム上のボタンが押せるようになれば、解決です。
なにかキーワードだけでも、教えてください。お願いします。
No.4ベストアンサー
- 回答日時:
> ■まず、クラスファイルは追加できたのですがprjServerの起動クラスの項目(clsPrj2)にどうやって追加するのか分かりませんでした。
起動クラスではなく、メインモジュール(Sub Main())でした。誤った情報を教えてしまってすいません。
> ■また、クラスファイルから(またはメインモジュールから)フォームをShowするやり方が分かりませんでした。(frmServer.show()ができませんでした。)
オブジェクト指向の概念を結構無視した作り方ですが、よければ参考にしてください。このやり方で「なんちゃってマルチスレッド」となるはずです。
※ちょいと寝ぼけ眼で書いてますんで、多少の間違いは勘弁してください。方向性は大丈夫だと思いますんで・・・。
(1)非同期サーバ起動フラグ格納クラス(仮にclsBoolとします)を作成し、publicメンバ変数(仮にboolean型のbFlag)を用意します(初期値:false)。
(2)frmServerクラスに、clsBool型のpublicメンバ変数(仮にcFlag)を追加します。
(3)Main()関数およびfrmServer.btnServer_Click()での処理を以下のようにします。
===== メインモジュール内 =====
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub Main()
Dim cBool As clsBool
Dim frmS As frmServer
Set frmS = New frmServer
Set cBool = New clsBool
Load frmS
set frmS.cFlag = cBool
frmS.Show
Do While 1
If cBool.bFlag = true Then
exit Do
Else
DoEvents
Sleep 1000
End If
Loop
AsynchronousClient.Main '非同期サーバ起動
frmS.Hide
Unload frmS
Set frmS = Nothing
Set cBool = Nothing
End Sub
======= frmServerクラス内 =======
private sub btnServer_Click()
cFlag.bflag = true
end sub
> ■文字だけの送受信なら、tcpClientクラスやtcpListnerクラスを使って簡単にできると思うのですが、ファイルの転送もできるのでしょうか?(その際、BinaryWriterとBinaryReaderを使えばいいのでしょうか?)しかし、スレッドを使わないとファイルを送受信している間は、他に何もできないのかも??
VBでファイル転送は経験ありませんが、個人的にはftpを使ったほうがいいような気もします。
明確な回答でなくてごめんなさい。
この回答への補足
レス遅れました。
マルチタスクにするためには、監視するスレッドが必要なのですね υ
VB.NETは、買ったばかりなので、なかなか難しいです。
大変遅くなってしまいましたが、だいぶ、考え方は理解できたので、締め切ろうと思います。
ご協力ありがとうございました。
(お礼と補足が逆になった事、締め切るまでに時間がかかった事をお詫びします。)
また、機会があれば教えてください。
私は、勿論、力不足ですが、できる範囲でお返しもしたいです。
レス遅れました。
眠いのに一所懸命アドバイスしてくれて、ありがとうございます。
publicメンバ変数というのが、分かりませんでした。メインモジュール内で、
Public Class clsBool
Dim bFlag As Boolean = False
End Class
と書いたのですが、上手くいきませんでした。
クラスファイルを追加してもダメでした。
後は助言して頂いた方法でも、引き続き frmServer.show() ができませんでした。
これ(↓)関係ありそうですが・・・。
http://park16.wakwak.com/~mimi/dotnet/misc/worke …
もうちょっと自分で試行錯誤してみます。
またお世話になるかもしれませんが、その時は宜しくお願いします。
No.3
- 回答日時:
>文字だけの送受信なら、tcpClientクラスやtcpListnerクラスを使って簡単にできると思うのですが、ファイルの転送もできるのでしょうか?
についてですが、
TcpClientクラス
http://www.microsoft.com/japan/msdn/library/defa …
に
>データを送受信するには、 GetStream メソッドを使用して
とあります
使ったことがないからよくわかっておりませんが、VB6でのWinSockコントロールのメソッドと類似しているので、MSDNを見る限りでは可能と思いますよ。
この回答への補足
実は、VB6のWinSockコントロールで、ファイル転送はできなかったですが、もっと勉強してがんばってみようと思いました。
まずは、VB6で修行(?)をつんで、VB.NETへ行きます(笑)
では、ありがとうございました。
(補足の欄にお礼を書いてしまって申し訳ありません)
NetworkStreamも使うみたいですね。
ただ、私はVB6でWinsockコントロールを使った事があるんですが、[winsockのオブジェクト名].SendData
(C:\Temp\Test.txt)みたいに書きたいのに書けない~って困った覚えがあります(汗)
そんなに簡単にコーディングできませんね(笑)
レスありがとうございます。
No.2
- 回答日時:
補足説明ありがとうございます。
もしかしたら、frmServer.BtnServer_click()内でAsynchronousSocketListener.Main()をコールしていることに問題があるのではないでしょうか?
.NETに詳しくないので具体的なお答えができませんが、StartListening()内で無限ループ(待ち状態)に入っているため、BtnServer_click()メソッドが終了できずに固まっているように思います。
恐らくプロジェクト2のスタートアップ(起動クラス)をfrmServerにしているのだと思いますので、こうされてみてはどうでしょう?
(1)起動クラス(仮にclsPrj2とします)を新規作成。そのクラスではfrmServerフォームを表示後、無限ループ(非同期サーバ起動待ち)に入る。非同期サーバ起動条件は、非同期サーバ起動フラグ(仮にisStartとします)がtrueのときのみとします。(このフラグの初期状態はfalse。falseの時はしばらくSleepして再度isStartフラグをチェックする。)
(2)frmServer.BtnServer_Click()メソッドで、非同期サーバ起動開始メンバ関数(仮にclsPrj2.start()とします)をコール。この関数ではisStartをtrueにセットするのみとします。(この関数でAsynchronousSocketListener.Main()をコールするとやはりフォームが固まるように見えてしまいます。)
(3)(1)の無限ループで、isStartがtrueになるので、AsynchronousSocketListener.Main()がコールされる。
これで、ボタンが固まるということはなくなると思います。あまり自身がありませんが、これで試してみてください。もし勘違いしてたらごめんなさい。
この回答への補足
ヒントありがとうございます。
イメージは掴めたんですがコーディングが・・・。ごめんなさい。
■まず、クラスファイルは追加できたのですがprjServerの起動クラスの項目(clsPrj2)にどうやって追加するのか分かりませんでした。
ですが、すでに選択できるクラスが AsynchronousSocketListener, frmServer, sub main となっていたので、AsynchronousSocketListenerとしてみました所、フォームが固まるという問題は解決しました。そもそもfrmServerを表示しないという奇策ですが・・・。
「btnServer_click()メソッドが終了できず」という表現がすごく参考になりました。
"<QUIT>"という文字が送られてきた時はサーバを終了するようにして、待ち状態の解除をするようにしました。
■また、クラスファイルから(またはメインモジュールから)フォームをShowするやり方が分かりませんでした。(frmServer.show()ができませんでした。)
Dim frmServer1 As New prjServer.frmServer
frmServer1.show()
と書いたのですが、frmServer1の「宣言が必要です」とでまして、ビルドエラーになってしまいます。
■なんか私がやっている事は、マルチスレッドのメリットを相殺している様な気がしてきました。
やっぱりスレッドを使わないでやるしかないのかな、私には。
Public Sub New()
End Sub 'New
がヒントなんでしょうかね?(汗)(オーバーロード??)
■文字だけの送受信なら、tcpClientクラスやtcpListnerクラスを使って簡単にできると思うのですが、ファイルの転送もできるのでしょうか?(その際、BinaryWriterとBinaryReaderを使えばいいのでしょうか?)しかし、スレッドを使わないとファイルを送受信している間は、他に何もできないのかも??
どなたかご存知の方があれば、ご教授ください。
的外れなことをしていたらごめんなさい>Musaffahさん
もうちょっと、がんばってみます。
No.1
- 回答日時:
VB.NETはよくわからないので、何もお手伝いできないかと思いますが、その前に状況をもう少し確認させてください。
(1)「プロジェクト2のButton1をクリックしたら固まる」という解釈でいいですか?
(2)その時、プロジェクト1は起動している状態ですか?また、プロジェクト2.Button1をクリックした後にプロジェクト1.Button1をクリックしてその状態になるの(要はソケット通信処理が終了しているのに・・・何故?)ですか?
(3)フォーム上にはButton1以外にもボタンがあるのですか?
この回答への補足
すみません、補足します。
(1)はい、そうです。
(2)プロジェクト2.Button1(サーバ)を押すとListen状態になり、プロジェクト1.Button1(クライアント)を押す度に、データが送受信され、サーバー側の出力ウィンドウに以下の様に表示されます。
Read 19 bytes from socket.
Data : This is a test<EOF>
Sent 19 bytes to client.
プロジェクト2.Button1(サーバ)を押した時点で、フォームが固まります。
ただし・・・
サーバプロジェクトは、(出力ウィンドウを見る必要がある為)VB.NET で実行しています。
クライアントは、ビルド済みの exe 本体から、起動してます。
(3)ないです。
サンプルコードをコピーして、フォームにあるボタンを押すと、非同期クライアントのmainと非同期サーバー ソケットのmainをCallするようになってます。
サンプルコードをそのまま使えるのなら、プログラマーは要らないわけで、大変皆様に失礼な質問なのですが、先に進む見込みがなくなってしまったので、ここで質問致しました。ヒントを下されば幸いです。
分かりにくいので、frmServer, btnServer, frmClient, btnClientと名前をつけます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript javascriptで移動ボタンを押した際に遷移するボタンを追記したい 1 2022/11/29 03:02
- JavaScript セレクトを全て選択されていないと、文字によるエラーメッセージを表示させるコードを調べています 2 2023/06/22 15:48
- JavaScript 入力フォームの javascript で メールアドレスの正規チェックをを行い、ボタンをクリックして 2 2022/04/27 16:06
- Access(アクセス) AccessVBAで降順にするテーブル作成クエリを使用して作成したテーブルを削除し同一のテーブル作成 1 2023/01/06 11:17
- JavaScript フォームが空欄の時にフォームの外をクリックすると、エラーが出るコードを調べています。 1 2023/06/25 11:51
- JavaScript sessionStorageを調べています。 1 2023/06/20 12:41
- JavaScript ①入力フォーム→②確認表示画面→③送信完了画面のコードを書いているのです、 入力フォームから受け取っ 2 2022/05/10 16:45
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- バッテリー・充電器・電池 車用のスマホの充電器で自動でホルダーが開閉して スマホを固定して充電も行う便利な物があります。 知人 1 2023/06/04 18:31
- その他(プログラミング・Web制作) google formsを使ったタスク依頼フォーム作成におけるご相談 1 2023/06/22 15:55
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
既定のコンストラクタがない?
-
VBA チェックボックスをオーバ...
-
C#でのjsonの扱い方を教えてく...
-
(UWSC) 「#32770」の意味わかり...
-
FriendとPublicの違い。。。
-
ダイアログ表示時にチェックボ...
-
オブジェクト指向 集約の実装...
-
イベントにAddHandlerされてい...
-
DLLの作り方および使い方について
-
WebBrowserコントロールを継承...
-
特定のビューへのポインタ取得...
-
DataContextについて
-
Serialize で困ってます!!
-
MFC モードレスDlgについて
-
関数のプロパティ
-
CDocumentの取得方法について
-
C++ protectedにアクセス不可
-
【ASP.NET】 独自で作成したク...
-
MFCのCListCtrlでスクロールを検出
-
DateAdd関数について質問があり...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
FriendとPublicの違い。。。
-
既定のコンストラクタがない?
-
イベントにAddHandlerされてい...
-
ダイアログ表示時にチェックボ...
-
エディットコントロールでEnter...
-
(UWSC) 「#32770」の意味わかり...
-
C++ protectedにアクセス不可
-
クラスのアドレスを引数として...
-
エディットコントロールのイベ...
-
【ASP.NET】 独自で作成したク...
-
MFCのドラッグ&ドロップについて
-
オーバーライド関数の呼び出し...
-
C++/CLIからC++の呼び出しで例外
-
ボタンのオーナードローについて
-
C++で継承元のクラスの代入演算...
-
MFCアプリのコマンドラインでパ...
-
DLLからEXEのクラスを呼び出す...
-
MFCのCListCtrlでスクロールを検出
-
オブジェクト指向 集約の実装...
-
ダイアログクラスのコントロー...
おすすめ情報