前回までの動作は、サーバー側/クライアント側共にブロッキングモードだったので、マルチスレッドを利用してサーバー側の見掛け上のハングアップ(応答なし)を回避してみる事に。
(クライアント側を敢えてスレッド分けする利点が・・・)
<注意点>
・動作はスレッド利用によりノンブロッキングモードです。
・クライアント側ソースの前回との相違は、以下のみ。
Dim message As String = "There is it!<EOF>"
・エラー処理は手抜きです。
お試し環境
Windows7 64bit Edition
Visual Basic 2008 AnyCPU対象
/*---- サーバー側 -------------------- お試し結果 --------------------------*/
Waiting for a connection...
Connected!
Waiting for a connection...
Received: There is it!<EOF>
Sent: THERE IS IT!<EOF>
/*----------------------------------------------------------------------------*/
/*---- クライアント側 ---------------- お試し結果 --------------------------*/
Sent: There is it!<EOF>
Received: THERE IS IT!<EOF>
/*----------------------------------------------------------------------------*/
/*---- サーバー側 ------------------ お試しソース -------------------------*/
'Imports System.Net
'Imports System.Net.Sockets
'Imports System.Text
Public Class Form1
Private Sub subThread2(ByVal obj As Object)
Dim clnt As Net.Sockets.TcpClient ' クライアント側ソケットのコピー
Dim stream As Net.Sockets.NetworkStream ' クライアント側との送受信ストリーム
' バイト列送受信バッファ
Dim sndBytes(1024) As Byte
Dim rcvBytes(1024) As Byte
Dim i As Integer
Dim msg As String
clnt = CType(obj, Net.Sockets.TcpClient)
Try
' クライアントとの送受信ストリーム取得
stream = clnt.GetStream()
' データを全て受信するまでループ
i = stream.Read(rcvBytes, 0, rcvBytes.Length)
While (i <> 0)
' 受信バイト列を文字列に変換
msg = System.Text.Encoding.ASCII.GetString(rcvBytes, 0, i)
Debug.Print("Received: {0}", msg)
' 受信データ処理
msg = msg.ToUpper()
sndBytes = System.Text.Encoding.ASCII.GetBytes(msg)
' 応答送信
stream.Write(sndBytes, 0, sndBytes.Length)
Debug.Print("Sent: {0}", msg)
i = stream.Read(rcvBytes, 0, rcvBytes.Length)
End While
' クライアント側ソケット解放
stream.Close()
clnt.Close()
Catch ex As Net.Sockets.SocketException
Debug.Print("SocketException : {0}", ex)
Throw ' 例外が呼出し元に伝わるかは未確認
Finally
clnt.Close()
End Try
End Sub
Private Sub subThread1(ByVal obj As Object)
Dim srv As Net.Sockets.TcpListener ' リスナー側ソケットのコピー
Dim client As Net.Sockets.TcpClient ' クライアント側ソケット
Dim t As Threading.Thread ' スレッド
srv = CType(obj, Net.Sockets.TcpListener)
Try
' 接続要求受け取り開始
While True
Debug.Print("Waiting for a connection... ")
' 接続要求許可待ちの間、プログラムは一時停止
client = srv.AcceptTcpClient()
Debug.Print("Connected!")
' スレッド開始
t = New Threading.Thread(AddressOf subThread2)
t.Start(client)
Threading.Thread.Sleep(0)
End While
Catch ex As Net.Sockets.SocketException
Debug.Print("SocketException : {0}", ex)
Finally
srv.Stop()
End Try
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim server As Net.Sockets.TcpListener ' リスナー側ソケット
Dim localAddr As Net.IPAddress ' ローカルIPアドレス
Dim port As Integer
Dim t As Threading.Thread ' スレッド
Try
' リスナーソケット作成
port = 22000
localAddr = Net.IPAddress.Parse("127.0.0.1")
server = New Net.Sockets.TcpListener(localAddr, port)
' クライアントからの受信接続要求リッスン開始
server.Start()
' スレッド開始
t = New Threading.Thread(AddressOf subThread1)
t.Start(server)
Threading.Thread.Sleep(0)
Catch ex As Net.Sockets.SocketException
Debug.Print("SocketException : {0}", ex)
End Try
End Sub
End Class
/*----------------------------------------------------------------------------*/
/*---- クライアント側 -------------- お試しソース -------------------------*/
'Imports System.Net
'Imports System.Net.Sockets
'Imports System.Text
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim client As Net.Sockets.TcpClient ' クライアントソケット
Dim port As Integer
Dim stream As Net.Sockets.NetworkStream ' 送受信ストリーム
Dim sndData(1024) As Byte ' バイト列送信バッファ
Dim rcvData(1024) As Byte ' バイト列受信バッファ
Dim rcvLen As Integer
Dim msg As String
Dim server As String = "127.0.0.1"
Dim message As String = "There is it!<EOF>"
Try
' クライアントソケット作成
port = 22000
client = New Net.Sockets.TcpClient(server, port)
' 送信文字列をバイト配列に変換
sndData = System.Text.Encoding.ASCII.GetBytes(message)
' 送受信ストリームを取得
stream = client.GetStream()
' サーバーにメッセージ送信
stream.Write(sndData, 0, sndData.Length)
Debug.Print("Sent: {0}", message)
' 応答データ受信
rcvLen = stream.Read(rcvData, 0, rcvData.Length)
msg = System.Text.Encoding.ASCII.GetString(rcvData, 0, rcvLen)
Debug.Print("Received: {0}", msg)
' ソケット解放
stream.Close()
client.Close()
Catch ex As ArgumentNullException
Debug.Print("ArgumentNullException: {0}", ex)
Catch ex As Net.Sockets.SocketException
Debug.Print("SocketException: {0}", ex)
End Try
End Sub
End Class
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*============================================================================*/