最近做实验要求实现一个UDP的聊天小程序,这个东西在VS.NET里面的MSDN里面有实例代码。我在这里还是做一些介绍,并加了一些扩充!
开发环境:VS.NET 2005(VB.NET)
1.新建一个解决方案,命名为UDPDemo;
2.在该解决方案下新建两个项目,分别命名为:ServerDemo,ClientDemo;
项目层次图,如下:
ServerDemo项目下,在FrmMain窗体中添加一个文本框,命名为txtMessage,允许多行。FrmMain.vb 代码如下:
Imports
System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Public Class FrmMain Class FrmMain
Private Const listenPort As Integer = 11000
Private done As Boolean = False
Private Sub StartListener()Sub StartListener()
Dim listener As New UdpClient(listenPort)
Dim groupEP As New IPEndPoint(IPAddress.Any, listenPort)
Try
While Not done
Me.Write("Waiting for broadcast" & vbCrLf)
Dim bytes As Byte() = listener.Receive(groupEP)
Me.Write(String.Format("Received broadcast from {0} :" & vbCrLf, groupEP.ToString()))
Me.Write(Encoding.ASCII.GetString(bytes, 0, bytes.Length) & vbCrLf)
End While
Catch e As Exception
Console.WriteLine(e.ToString())
Finally
listener.Close()
End Try
End Sub 'StartListener
Private Sub FrmMain_Load()Sub FrmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim _Thread As System.Threading.Thread = Nothing
Try
_Thread = New System.Threading.Thread(AddressOf Me.StartListener)
_Thread.Start()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
End Sub
Private Sub Write()Sub Write(ByVal str As String)
Me.txtMessage.BeginInvoke(New Action(Of String)(AddressOf Me.txtMessage.AppendText), str)
End Sub
Private Sub FrmMain_FormClosing()Sub FrmMain_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
done = True
Application.ExitThread()
End Sub
End Class
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Public Class FrmMain Class FrmMain
Private Const listenPort As Integer = 11000
Private done As Boolean = False
Private Sub StartListener()Sub StartListener()
Dim listener As New UdpClient(listenPort)
Dim groupEP As New IPEndPoint(IPAddress.Any, listenPort)
Try
While Not done
Me.Write("Waiting for broadcast" & vbCrLf)
Dim bytes As Byte() = listener.Receive(groupEP)
Me.Write(String.Format("Received broadcast from {0} :" & vbCrLf, groupEP.ToString()))
Me.Write(Encoding.ASCII.GetString(bytes, 0, bytes.Length) & vbCrLf)
End While
Catch e As Exception
Console.WriteLine(e.ToString())
Finally
listener.Close()
End Try
End Sub 'StartListener
Private Sub FrmMain_Load()Sub FrmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim _Thread As System.Threading.Thread = Nothing
Try
_Thread = New System.Threading.Thread(AddressOf Me.StartListener)
_Thread.Start()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
End Sub
Private Sub Write()Sub Write(ByVal str As String)
Me.txtMessage.BeginInvoke(New Action(Of String)(AddressOf Me.txtMessage.AppendText), str)
End Sub
Private Sub FrmMain_FormClosing()Sub FrmMain_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
done = True
Application.ExitThread()
End Sub
End Class
ClientDemo项目下,在FrmMain窗体中添加控件,如图所示:
代码部分如下:
Imports
System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Public Class FrmMain Class FrmMain
Private Sub Send()Sub Send(ByVal str As String)
Dim s As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Dim broadcast As IPAddress = IPAddress.Parse(Me.txtIPAddress.Text.Trim())
Dim sendbuf As Byte() = Encoding.ASCII.GetBytes(str)
Dim ep As New IPEndPoint(broadcast, 11000)
s.SendTo(sendbuf, ep)
Me.Write(String.Format("向服务器发送消息:{0}{1}{2}", vbCrLf, str, vbCrLf))
End Sub
Private Sub btnClose_Click()Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
Application.Exit()
End Sub
Private Sub btnSend_Click()Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Me.Send(Me.txtMessage.Text)
Me.txtMessage.Text = String.Empty
End Sub
Private Sub Write()Sub Write(ByVal str As String)
Me.txtInfo.BeginInvoke(New Action(Of String)(AddressOf Me.txtInfo.AppendText), str)
End Sub
End Class
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Public Class FrmMain Class FrmMain
Private Sub Send()Sub Send(ByVal str As String)
Dim s As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Dim broadcast As IPAddress = IPAddress.Parse(Me.txtIPAddress.Text.Trim())
Dim sendbuf As Byte() = Encoding.ASCII.GetBytes(str)
Dim ep As New IPEndPoint(broadcast, 11000)
s.SendTo(sendbuf, ep)
Me.Write(String.Format("向服务器发送消息:{0}{1}{2}", vbCrLf, str, vbCrLf))
End Sub
Private Sub btnClose_Click()Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
Application.Exit()
End Sub
Private Sub btnSend_Click()Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Me.Send(Me.txtMessage.Text)
Me.txtMessage.Text = String.Empty
End Sub
Private Sub Write()Sub Write(ByVal str As String)
Me.txtInfo.BeginInvoke(New Action(Of String)(AddressOf Me.txtInfo.AppendText), str)
End Sub
End Class
需要注意的是,广播地址应为服务端运行的主机地址!
这个程序可以基本实现了UDP通讯,但是有个问题,就是服务端程序关闭后,其监听线程仍然还在后台执行着,这个问题不知道如何解决!