最終更新日 2005 年 7 月 14 日
サンプル
コードのダウンロード (vbmigtips_Socket.exe, 122
KB)
ソケットを使用してプロセス間および、マシン間での通信を行いたい場合があると思います。そこで今回は、ソケットを使用してアプリケーション間を
TCP 通信し、データの送受信を行う方法について紹介します。
Visual Basic 6.0 では、Winsock
コントロールを使用してソケット通信を実現します。[プロジェクト]メニューの[コンポーネント]を選択し、「コンポーネント」ダイアログを表示します。ダイアログの[コントロール]タブで「Microsoft
Winsock Control 6.0」のチェックボックスをオンにして、[OK]ボタンを選択します。すると、Winsock
コントロールが追加されます。
まず、リモートホスト (サーバー) 側のアプリケーション (図1)
を作成します。
.gif)
図1
Form に Winsock
コントロールを貼り付けます。実装コードは以下のとおりです。
|
Private Sub Command1_Click()
Winsock(0).LocalPort
= "1111"
Winsock(0).Listen
Command1.Enabled =
False
Command2.Enabled =
True
End Sub
Private Sub Command2_Click()
Dim iintLoop As
Integer
For iintLoop =
0 To intConnectMax
Winsock(iintLoop).Close
Next
Command1.Enabled =
True
Command2.Enabled =
False
End Sub
Private Sub
Winsock_ConnectionRequest(Index As Integer, ByVal requestID As
Long)
intConnectMax =
intConnectMax + 1
Winsock(intConnectMax).Accept
requestID
End Sub
Private Sub
Winsock_DataArrival(Index As Integer, ByVal bytesTotal As
Long)
Dim strBuf As
String
Winsock(Index).GetData
strBuf
Text1.Text =
"クライアントから「" & strBuf & "」を受信しました。"
Winsock(Index).SendData
StrConv(strBuf, vbWide)
End
Sub |
リスト1
上記 (リスト1)
の「Winsock(0).LocalPort =
"1111"」でポート番号を指定し、「Winsock(0).Listen」で相手アプリケーションから接続要求を待ちます。接続要求が来ると
ConnectionRequest イベントが発生します。ConnectionRequest
イベントでは、相手アプリからの接続要求を受け付けます。また、相手のアプリケーション (クライアント)
からデータが送信されてきたときに発生する DataArrival
イベントで、受信されたデータをテキストボックスに表示し、クライアントにデータを返信します。「Winsock(Index).GetData
strBuf」でクライアントから送信されてきたデータを取得し、「Text1.Text = "クライアントから「" &
strBuf & "」を受信しました。" 」でテキストに表示します。「Winsock(Index).SendData
StrConv(strBuf,
vbWide)」でクライアントにデータを返信します。
続いて、クライアント側のアプリケーション (図2)
を作成します。
.gif)
図2
クライアント側のアプリケーション (図2) は、Form を Load
時にリモートホスト側に接続し、[送信]ボタンを選択すると、テキストボックス内のデータを上記で作成したリモートホスト側のアプリケーションに送信されます。そして、リモートホスト側から返信が帰ってきます。こちらも
Form に Winsock コントロールを貼り付けます。クライアント側の実装コードは以下のとおりです。
|
Private Sub Form_Load()
Winsock1.LocalPort =
0
Winsock1.RemoteHost
= "localhost"
Winsock1.RemotePort
= "1111"
Winsock1.Connect
End Sub
Private Sub Command1_Click()
Winsock1.SendData
Text1.Text + vbCrLf
End Sub
Private Sub
Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim strBuf As
String
Winsock1.GetData
strBuf
Text2.Text =
"リモートホストから「" & strBuf & " 」を受信しました。"
End
Sub |
リスト2
上記 (リスト2)
の「Winsock1.LocalPort = 0」では、一度使ったローカルポートを再使用するときにエラーが発生するため O
クリアします。「Winsock1.RemoteHost = "localhost"」「Winsock1.RemotePort =
"1111"」でサーバーマシンのホスト名とサーバーアプリケーションに対応するポート番号を指定します。そして「Winsock1.Connect」でコネクションの接続要求を送信します。
「Winsock1.SendData
Text1.Text + vbCrLf」で textBox1 のデータをサーバーに送信します。 DataArrival
イベントの「Winsock1.GetData strBuf」ではサーバーから受信されてきたデータを取得し、「Text2.Text =
"リモートホストから「" & strBuf & "
」を受信しました。"」でテキストボックスに表示します。
リスト1 とリスト2
を実装し、実行してみましょう。まず、クライアント側のアプリケーション (リスト1) を実行し、[接続]ボタンを選択します
(図1)。次に、クライアント側のアプリケーション (リスト2) を実行します
(図2)。これにより、リモートホスト側とクライアント側のアプリケーションが接続されます。図2
のテキストボックスにデータを入力し、[送信]ボタンを選択すると、入力したデータがリモートホスト側に送信され、テキストボックスのデータを表示します
(図3)。
.gif)
図3
テキストに受信されたデータを表示後、受信されたデータをクライアント側に送信します。すると、データを受信したクライアント側は、テキストボックスに受信されたデータを表示します
(図4)。
.gif)
図4
このように、Visual Basic 6.0 では Winsock
コントロールを使用しました。一方、Visual Basic .NET では System.Net.Sockets
名前空間を使用して実装します。そこで続いては、Visual Basic .NET
での実装方法について紹介します。
まず、リモートホスト (サーバー)
側のアプリケーションを作成します。実装コードは以下のとおりです。
|
Private intPortNo As Integer =
1111
Private objTcpListener As New
System.Net.Sockets.TcpListener(intPortNo)
Private Sub Button1_Click(ByVal
sender As System.Object, ByVal e As System.EventArgs) Handles
Button1.Click
objTcpListener.Start()
Button1.Enabled
= False
Button2.Enabled
= True
Timer1.Start()
End Sub
Private Sub Button2_Click(ByVal
sender As System.Object, ByVal e As System.EventArgs) Handles
Button2.Click
objTcpListener.Stop()
Button1.Enabled
= True
Button2.Enabled
= False
Timer1.Stop()
End Sub
Private Sub Timer1_Tick(ByVal
sender As Object, ByVal e As System.EventArgs) Handles
Timer1.Tick
Dim
bytReceiveBuffer(255) As Byte
Dim
bytSendBuffer() As Byte
Dim
intReceiveLength As Integer
Dim
objNetworkStream As System.Net.Sockets.NetworkStream
Dim
objTcpClient As System.Net.Sockets.TcpClient
Dim
strReceivedData As String
With
objTcpListener
If .Pending =
False Then
Exit Sub
End If
objTcpClient =
.AcceptTcpClient
With
objTcpClient
objNetworkStream =
.GetStream
With
objNetworkStream
Do
If
.DataAvailable = True Then
intReceiveLength =
.Read(bytReceiveBuffer, 0, bytReceiveBuffer.Length)
strReceivedData
&=
System.Text.Encoding.Default.GetString(bytReceiveBuffer). Substring(0,
intReceiveLength)
ElseIf Not
strReceivedData Is Nothing Then
TextBox1.Text
= "クライアントから「" & strReceivedData & "」受信しました。"
bytSendBuffer
= System.Text.Encoding.Default.GetBytes(strReceivedData)
.Write(bytSendBuffer,
0, bytSendBuffer.Length)
Exit Do
End If
Loop
End With
.Close()
End With
End With
End Sub
|
リスト3
上記 (リスト3)
の「objTcpListener.Start()」で TCP
の受信接続の待機を開始し、「Timer1.Start()」でタイマをスタートさせます。「objTcpListener.Stop()」でリスナを閉じ、「Timer1.Stop()」でタイマを止めます。
「If
.Pending = False Then ... End
If」では、待機中に接続要求が無かった場合、プロシージャを抜けます。「objTcpClient =
.AcceptTcpClient」では、データの送受信に使用できる TCP クライアントを取得し、「objNetworkStream =
.GetStream」でデータを送受信するために使用するストリームを取得します。「strReceivedData &=
System.Text.Encoding.Default.GetString(bytReceiveBuffer).Substring(0,
intReceiveLength)」で TCP クライアントから送信されたデータを取得し、「bytSendBuffer =
System.Text.Encoding.Default.GetBytes(strReceivedData)」で String
に変換します。読み取ったデータは「TextBox1.Text = "クライアントから「" & strReceivedData
& "」受信しました。"」でテキストボックスに表示します。そして、「bytSendBuffer =
System.Text.Encoding.Default.GetBytes(strReceivedData)」で Bytes
の配列に変換し、そのデータを「.Write(bytSendBuffer, 0, bytSendBuffer.Length)」で TCP
クライアントに返信します。最後に「.Close()」で TCP
接続を終了します。
続いて、クライアント側のアプリケーションを作成します。実装コードは以下のとおりです。
|
Private intPortNo As Integer =
1111
Private objNetStream As
System.Net.Sockets.NetworkStream
Private objTcpClient As
System.Net.Sockets.TcpClient
Private Sub Button1_Click(ByVal
sender As System.Object, ByVal e As System.EventArgs) Handles
Button1.Click
Dim
bytReceiveBuffer(255) As Byte
Dim
bytSendBuffer As Byte()
Dim
intDataLength As Integer
Dim
strReceivedData As String
objTcpClient =
New System.Net.Sockets.TcpClient
With
objTcpClient
Try
objTcpClient.Connect("localhost",
intPortNo)
objNetStream =
.GetStream
With
objNetStrea
bytSendBuffer =
System.Text.Encoding.Default.GetBytes(TextBox1.Text)
.Write(bytSendBuffer,
0, bytSendBuffer.Length)
Do
If
.DataAvailable Then
intDataLength
= .Read(bytReceiveBuffer, 0, bytReceiveBuffer.Length)
strReceivedData
&=
System.Text.Encoding.Default.GetString(bytReceiveBuffer). Substring(0,
intDataLength)
ElseIf Not
strReceivedData Is Nothing Then
TextBox2.Text
= "リモートホストから「" & strReceivedData & " 」を受信しました。"
Exit Do
End If
Loop
End With
Catch Ex As
Exception
MsgBox(Ex.Message)
End Try
.Close()
End With
End
Sub |
リスト4
上記 (リスト4)
の「objTcpClient.Connect("localhost",
intPortNo)」でリモートホストと接続します。「bytSendBuffer =
System.Text.Encoding.Default.GetBytes(TextBox1.Text)」でデータをリモートホストへ送信します。リスト4
の「Do ... Loop」でリモートホストからの返信を受信します。受信されたデータは「TextBox2.Text =
"リモートホストから「" & strReceivedData & "
」を受信しました。"」でテキストボックスに表示します。最後に「.Close()」で TCP 接続を終了します。
リスト3
とリスト4 を実装し、実行してみましょう。まず、クライアント側のアプリケーション (リスト1) を実行し、[接続]ボタンを選択します
(図1)。次に、クライアント側のアプリケーション (リスト2) を実行します
(図2)。これにより、リモートホスト側とクライアント側のアプリケーションが接続されます。図2
のテキストボックスにデータを入力し、[送信]ボタンを選択すると、入力したデータがリモートホスト側に送信され、テキストボックスのデータを表示します
(図3)。テキストに受信されたデータを表示後、受信されたデータをクライアント側に送信します。すると、データを受信したクライアント側は、テキストボックスに受信されたデータを表示します
(図4)。