基于C#的UDP通信(使用UdpClient实现,包含发送端和接收端)
UDP不属于面向连接的通信,在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的ICQ和QQ就是使用的UDP协议。
我们通过UDP进行信息收发的时候,没有严格客户端和服务端的区别,它不同于UDP,UDP 必须建立可靠连接之后才可以通信,而UDP随时都可以给指定的ip和端口所对应进程发送消息。UDP发送消息时需要绑定自己IP 和 端口号,接收消息的时候没有特殊限制,只要有人给自己发送,自己在线,就可以接收。
(网上例子很多,但是总有一点地方看不懂。下面附上我的小例子,仅供参考。)
发送端:
1 using System; 2 using System.Text; 3 using System.Windows.Forms; 4 using System.Net.Sockets; 5 using System.Net; 6 7 namespace client 8 { 9 public partial class Form1 : Form 10 { 11 public Form1() 12 { 13 InitializeComponent(); 14 } 15 16 //初始化一个UdpClient的新实例 17 UdpClient sendUdpClient = new UdpClient(); 18 19 //单击事件 20 private void btn_send_Click(object sender, EventArgs e) 21 { 22 string message = txt_sendmsg.Text; 23 24 if(string.IsNullOrEmpty(message)) 25 { 26 MessageBox.Show("发送内容不能为空!"); 27 txt_sendmsg.Focus(); 28 return; 29 } 30 31 //用指定IP地址和端口号初始化IPEndPoint类的新实例 32 IPEndPoint local = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888); 33 34 //将数据报发送至指定主机 35 sendUdpClient.Send(Encoding.UTF8.GetBytes(message), message.Length, local); 36 37 } 38 } 39 }
接收端:
1 using System; 2 using System.Text; 3 using System.Windows.Forms; 4 using System.Net; 5 using System.Net.Sockets; 6 using System.Threading; 7 8 namespace server 9 { 10 public partial class Form1 : Form 11 { 12 public Form1() 13 { 14 InitializeComponent(); 15 } 16 17 private void Form1_Load(object sender, EventArgs e) 18 { 19 //初始化新线程用来接收消息 20 Thread myThread = new Thread(ReceiveMsg); 21 22 //设为后台线程 23 myThread.IsBackground = true; 24 25 //开启线程 26 myThread.Start(); 27 } 28 29 private UdpClient receiveUdpClient; 30 31 private const int port = 8888; 32 33 IPAddress ip = IPAddress.Parse("127.0.0.1"); 34 35 //接收消息 36 private void ReceiveMsg() 37 { 38 //用指定IP地址和端口号初始化IPEndPoint类的新实例 39 IPEndPoint local = new IPEndPoint(ip, port); 40 41 //初始化一个UdpClient的新实例并绑定到本地 42 receiveUdpClient = new UdpClient(local); 43 44 while(true) 45 { 46 try 47 { 48 //返回由主机发来的数据报 49 byte[] receiveBytes = receiveUdpClient.Receive(ref local); 50 51 string receivemsg = Encoding.UTF8.GetString(receiveBytes, 0, receiveBytes.Length); 52 ShowMessage(lst_receivemsg, receivemsg); 53 } 54 catch 55 { 56 break; 57 } 58 } 59 } 60 61 // 通过委托回调机制显示消息内容 62 delegate void ShowMessageDelegate(ListBox listbox, string text); 63 64 private void ShowMessage(ListBox listbox, string text) 65 { 66 //如果控件的 Handle 是在与调用线程不同的线程上创建的(此时,您必须通过 Invoke 方法对控件进行调用),则为 true;否则为 false。 67 //如果从另一个线程调用控件的方法,那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。 68 if (listbox.InvokeRequired) 69 { 70 ShowMessageDelegate d = ShowMessage; 71 listbox.Invoke(d, new object[] { listbox, text }); 72 } 73 else 74 { 75 listbox.Items.Add(text); 76 } 77 } 78 } 79 }