Imports System.Net, System.Net.Sockets
Public Class frmServer
Dim serverSocket As Socket
Dim clientSocket As Socket
Private Sub frmServer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
serverSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Dim IpEndPoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 8800)
serverSocket.Bind(IpEndPoint)
serverSocket.Listen(5)
serverSocket.BeginAccept(New AsyncCallback(AddressOf OnAccept), Nothing)
End Sub
Private Sub OnAccept(ByVal ar As IAsyncResult)
clientSocket = serverSocket.EndAccept(ar)
serverSocket.BeginAccept(New AsyncCallback(AddressOf OnAccept), Nothing)
AddClient(clientSocket)
End Sub
Delegate Sub _AddClient(ByVal client As Socket)
Private Sub AddClient(ByVal client As Socket)
If InvokeRequired Then
Invoke(New _AddClient(AddressOf AddClient), client)
Exit Sub
End If
Dim lvi As New ListViewItem(client.LocalEndPoint.ToString)
lvi.Tag = client
lsvClients.Items.Add(lvi)
End Sub
Private Sub Send(ByVal msg As String, ByVal client As Socket)
Dim sendBytes As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(msg)
client.BeginSend(sendBytes, 0, sendBytes.Length, SocketFlags.None, New AsyncCallback(AddressOf OnSend), client)
End Sub
Private Sub OnSend(ByVal ar As IAsyncResult)
Dim client As Socket = ar.AsyncState
client.EndSend(ar)
End Sub
Private Sub SendMessageToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SendMessageToolStripMenuItem.Click
Send("Message from server", lsvClients.SelectedItems(0).Tag)
End Sub
End Class
Client
Imports System.Net, System.Net.Sockets
Public Class frmClient
Dim clientSocket As Socket
Dim byteData(1023) As Byte
Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
clientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Dim ipAddress As IPAddress = ipAddress.Parse("127.0.0.1")
Dim ipEndPoint As IPEndPoint = New IPEndPoint(ipAddress, 8800)
clientSocket.BeginConnect(ipEndPoint, New AsyncCallback(AddressOf OnConnect), Nothing)
End Sub
Private Sub OnConnect(ByVal ar As IAsyncResult)
clientSocket.EndConnect(ar)
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, _
New AsyncCallback(AddressOf OnRecieve), clientSocket)
End Sub
Private Sub OnRecieve(ByVal ar As IAsyncResult)
Dim client As Socket = ar.AsyncState
client.EndReceive(ar)
Dim bytesRec As Byte() = byteData
Dim message As String = System.Text.ASCIIEncoding.ASCII.GetString(bytesRec)
Read(message)
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, _
New AsyncCallback(AddressOf OnRecieve), clientSocket)
End Sub
Delegate Sub _Read(ByVal msg As String)
Private Sub Read(ByVal msg As String)
If InvokeRequired Then
Invoke(New _Read(AddressOf Read), msg)
Exit Sub
End If
RichTextBox1.Text &= msg
End Sub
End Class
ซึ่งเมื่อมีการ connect ไปยัง Server แล้ว จะแสดง IPAddress กับ Port ซึ่งถ้ารันเครื่องอื่นที่ไม่ใช้เครื่องที่รันตัว Server มันแสดง IPAddress ไม่ตรงกับเครื่องที่ส่งมาอะครับ
Private Sub GetIPAddress()
Dim strHostName As String
Dim strIPAddress As String
strHostName = System.Net.Dns.GetHostName()
strIPAddress = System.Net.Dns.GetHostByName(strHostName).AddressList(0).ToString()
MessageBox.Show("Host Name: " & strHostName & "; IP Address: " & strIPAddress)
End Sub
คือ ถ้าเปลี่ยน ipAddress.Parse("127.0.0.1") เป็นชื่อเครื่อง ไม่ได้ครับ จะทำให้โปรแกรมเปิดไม่ได้ หรือถ้าเปลี่ยนเป็น IP ของเครื่องที่รันโปรแกรมมันก็ connect ไปยัง server ไม่ได้อยู่ดีครับ
ง่ายๆเลย ถ้าเปลี่ยน ipAddress.Parse เป็น IP อะไร มันก็จะวิ่งไปหาตัว Server ตัวนั้นครับ ซึ่งค่าที่ได้จากตัว server ก็จะได้ค่าออกมาเป็น IP ที่เรา connect มาครับ
ตัวอย่างเช่น
server รันที่เครื่อง IP 192.168.0.22
client ตัวแรกรันที่เครื่องเดียวกับ Server เมื่อเปลี่ยน ipAddress.Parse("127.0.0.1") หรือ ipAddress.Parse("192.168.0.22") Connect แล้ว server แสดงผล ปกติครับ 192.168.0.22:8800
client ตัวที่สองรันคนละเครื่องกับ Server เมื่อเปลี่ยน ipAddress.Parse("192.168.0.22") Connect แล้ว server แสดงผล เหมือนเดิมครับคือ 192.168.0.22:8800 ซึ่งจริงๆแล้วเครื่องนี้ IP 192.168.0.25 ซึ่งถ้าเปลี่ยน ipAddress.Parse("192.168.0.25") มันก็ไม่สามารถ connect ไปยัง server ที่รันไว้ในเครื่องแรกอะครับ
ผมดัดแปลงนิดหน่อยครับคือ ให้มันแสดง IP ในส่วนหัวของโปรแกรมเพื่อจะได้ทราบว่าเครื่องที่รัน IP อะไร และก็เปลี่ยน
ipAddress.Parse() ให้รับค่าจาก Textbox ครับ
รัน server กับ client เครื่องเดียวกัน
รัน client ตัวที่สอง
คือผมอยากได้ให้มันแสดง IP เครื่องที่ส่งมาให้ตรง หรือไม่ก็แสดงเป็นชื่อเครื่องที่ส่งมาไปเลย เวลาแสดงที่ server จะได้แสดงถูกว่ามีการเชื่อมต่อจากเครื่องไหนมาอะครับ