|
分類:[ASP.NET (VB)]
.NET Framework4.5
言語:Visual Basic
Windowsフォームアプリケーション
とあるサイトのサンプルからTCP通信のフォームアプリケーションを作ろる為に勉強しています。
そのサイトのサンプルではサーバー側とクライアント側をラジオボタンによって切り分けています。
私はそれをサーバー側とクライアント側に分けて、二つのフォームアプリケーションを作ろうとしています。
ほとんどサンプルを流用しているので、TCP通信のところは問題なく繋がったのですが、
サーバー側のアプリケーションでクライアントからの接続を待機中のスレッドを終了させようとするとフリーズしてしまいます。
サンプルでは特に問題なく終了できるのになぜ私の方では固まるのかがわかりません。
スレッドやTCP通信等に触れるのも初めてのことであり、何か根本的に理解できていない部分もあるのではないかと思い、質問させて頂きました。
また、サブスレッドをAbortで終了させるのもあまりよくないと聞きます。
接続待機中のスレッドを終了させる方法が何かありましたら、そちらもお聞きしたいと思います。
どうぞ、よろしくお願いします。
↓サーバー側の問題箇所の部分を書いたものです。
Imports System.Net.Sockets
Imports System.Threading
Public Class Form1
'サーバー設定
Dim server As TcpClient = Nothing
'サーバーのリスナー設定
Dim listener As TcpListener = Nothing
'サーバーのセカンドスレッドの設定
Dim threadServer As Thread = Nothing
'デリゲート宣言
'別スレッドからメインスレッドのテキストボックスに書き込むデリゲート
Delegate Sub dlgWriteText(ByVal text As String)
'引数を持たない汎用のデリゲート
'ストップボタンを押す等に使用
Delegate Sub dlgMydelegate()
'ソケット通信の開始処理
'Startボタン押下
Private Sub StartServerbtn_Click(sender As Object, e As EventArgs) Handles StartServerbtn.Click
StartSock()
End Sub
'ソケット通信開始
Private Sub StartSock()
'サーバースタート
Dim OpenFlg As Boolean
OpenFlg = ServerStart()
picIndicator.BackColor = Color.Green
'ボタンのenableを変える
If OpenFlg Then
StartServerbtn.Enabled = False
StopServerbtn.Enabled = True
End If
End Sub
'セカンドスレッドの作成とサーバーのスタート
Private Function ServerStart() As Boolean
'ListenするIPアドレス
Dim ipString As String
Dim ipAdd As System.Net.IPAddress
'Listenするポート番号
Dim port As Integer
'サーバーのIPアドレス(または、ホスト名)とポート番号をテキストボックスから取得
ipString = textBoxIp.Text
ipAdd = System.Net.IPAddress.Parse(ipString)
port = Integer.Parse(textBoxPortNo.Text)
'TcpListenerを使用してサーバーの接続の確立
Try
'lisenerが無い場合
If listener Is Nothing Then
listener = New TcpListener(ipAdd, port)
End If
'クライアント接続要求の受付開始
listener.Start()
'スレッドの作成と開始
threadServer = New Thread(New ThreadStart(AddressOf ServerListen))
threadServer.Start()
Return True
Catch ex As Exception
'エラーが起きた
listener.Stop()
picIndicator.BackColor = Color.Navy
Return False
End Try
End Function
Private Sub ServerListen()
'クライアントの要求があったら、接続を確立する
'クライアントの要求が有るまでここで待機する
server = listener.AcceptTcpClient()
'インジケータの色を変える
'バックカラーの変更はデリゲートの必要は無し
picIndicator.BackColor = Color.LightGreen
'クライアントとの間の通信に使用するストリームを取得
Dim stream As NetworkStream = server.GetStream()
'受信文字が入る。
'この数字は少なくても可、少ない場合はLoopが何回か実行される
Dim bytes(1000) As Byte
'受信が無い場合はここで待機する
'文字受信が有った場合とクライアントが接続を切った場合に
'次のステップに進む
Dim intCount As Integer = stream.Read(bytes, 0, bytes.Length)
End Sub
Private Sub StopServerbtn_Click(sender As Object, e As EventArgs) Handles StopServerbtn.Click
StopSock()
End Sub
Private Sub StopSock()
'サーバーストップ
CloseServer()
StartServerbtn.Enabled = True
StopServerbtn.Enabled = False
End Sub
'サーバーのクローズ
Private Sub CloseServer()
'サーバーのインスタンスが有って、接続されていたら
If server IsNot Nothing AndAlso server.Connected Then
server.Close()
End If
Try
'スレッドは必ず終了させること
If threadServer IsNot Nothing Then
threadServer.Abort()
End If
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try
'インディケータの色を変える
picIndicator.BackColor = Color.Navy
End Sub
End Class
|