Udp通讯(零基础)
生活随笔
收集整理的這篇文章主要介紹了
Udp通讯(零基础)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前面學習了Tcp通訊之后聽老師同學們講到Udp也可以通訊,實現還要跟簡單,沒有繁瑣的連接,所以最近學習了一下,記錄下來以便忘記,同時也發表出來與大家相互學習,下面是我自己寫的一個聊天例子,實現了群聊私聊等功能。
通訊類(UdpInfo)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Model 8 { 9 [Serializable] 10 public class UdpInfo 11 { 12 public string Name { get; set; } 13 public string Ip { get; set; } 14 public string Port { get; set; } 15 public string Message { get; set; } 16 public int Types { get; set; }//消息的類型 17 public bool IsFist { get; set; }//判斷加載的成員是否是第一個 18 public string ToName { get; set; }//與誰私聊 19 public string LoginName { get; set; }//新加入成員的名字 20 } 21 } View Code?
服務器(Server)
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 using System.Net; 11 using System.Net.Sockets; 12 using System.Threading; 13 using System.IO; 14 using System.Runtime.Serialization.Formatters.Binary; 15 using Model; 16 17 namespace Server 18 { 19 public partial class forUdp : Form 20 { 21 public forUdp() 22 { 23 InitializeComponent(); 24 } 25 UdpClient server = null; 26 IPEndPoint ipEndPoint = null; 27 List<IPEndPoint> pointList = new List<IPEndPoint>();//成員集合 28 private delegate void BindDelegate(UdpInfo u);//(綁定信息) 29 BindDelegate bd = null; 30 private bool flag;//是否為添加的第一個成員 31 private string loginName; 32 private void Form1_Load(object sender, EventArgs e) 33 { 34 txtPort.Text = "9018";//默認的端口 35 } 36 public void Receices()//接收客戶端的消息 37 { 38 while (true) 39 { 40 try 41 { 42 byte[] bytes = server.Receive(ref ipEndPoint);//獲取消息 43 UdpInfo u = DeserializeObject(bytes) as UdpInfo; 44 bd = new BindDelegate(BindRtb); 45 this.Invoke(bd, u); 46 } 47 catch (Exception) 48 { 49 server.Close();//有異常關閉服務 50 } 51 } 52 } 53 public object DeserializeObject(byte[] pBytes)//反序列化二進制為對象 54 { 55 object newOjb = null; 56 if (pBytes == null) 57 return newOjb; 58 MemoryStream memory = new MemoryStream(pBytes); 59 memory.Position = 0; 60 BinaryFormatter formatter = new BinaryFormatter(); 61 newOjb = formatter.Deserialize(memory); 62 memory.Close(); 63 return newOjb; 64 } 65 public byte[] SerializeObject(object pObj)//序列化對象為二進制的數 66 { 67 if (pObj == null) 68 return null; 69 MemoryStream memory = new MemoryStream(); 70 BinaryFormatter formatter = new BinaryFormatter(); 71 formatter.Serialize(memory, pObj); 72 memory.Position = 0; 73 byte[] read = new byte[memory.Length]; 74 memory.Read(read, 0, read.Length); 75 memory.Close(); 76 return read; 77 } 78 public void BindRtb(UdpInfo u) //添加信息,綁定信息 79 { 80 if(u.Types == 0)//如果消息類型為上線 81 { 82 pointList.Add(ipEndPoint);//添加成員 83 //u.Name = "1"; 84 //獲取需要的基本信息 85 loginName = u.Name; 86 u.Ip = ipEndPoint.ToString().Split(':')[0]; 87 u.Port = ipEndPoint.ToString().Split(':')[1]; 88 byte[] bytes = SerializeObject(u); 89 ListViewItem item = new ListViewItem(u.Name);//綁定添加到成員列表上 90 item.SubItems.Add(u.Ip); 91 item.SubItems.Add(u.Port); 92 lvInfo.Items.Add(item);//顯示成員信息 93 BindListView(loginName);//成員發生改變的時候,發送成員信息給客戶端,刷新客戶端的成員信息 94 } 95 else if (u.Types == 1)//如果消息的類型是群聊的話就執行 96 { 97 foreach (ListViewItem items in lvInfo.Items)//循環每個成員 98 { 99 IPAddress ip = IPAddress.Parse(items.SubItems[1].Text); 100 IPEndPoint ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[2].Text)); 101 byte[] bytes = SerializeObject(u); 102 server.Send(bytes, bytes.Length, ipEndPoint);//給每個用戶發送信息 103 } 104 } 105 else if (u.Types == 2)//消息的類型是私聊 106 { 107 foreach(ListViewItem items in lvInfo.Items) 108 { 109 //如果該成員是指定成員才發送信息 110 if(u.ToName.Equals(items.SubItems[0].Text)) 111 { 112 IPAddress ip = IPAddress.Parse(items.SubItems[1].Text); 113 IPEndPoint ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[2].Text)); 114 byte[] bytes = SerializeObject(u); 115 server.Send(bytes, bytes.Length, ipEndPoint);//發送消息給指定的用戶 116 } 117 } 118 } 119 else if(u.Types == 3)//如果消息的類型是下線的話 120 { 121 IPEndPoint ipEndPoint = null; 122 foreach (ListViewItem items in lvInfo.Items)//循環每個成員 123 { 124 IPAddress ip = IPAddress.Parse(items.SubItems[1].Text); 125 ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[2].Text)); 126 if(items.SubItems[0].Text.Equals(u.Name)) 127 { 128 lvInfo.Items.Remove(items);//從ListView集合中移除 129 pointList.Remove(ipEndPoint);//從List<IPEndPoint>集合中移除 130 continue; 131 } 132 byte[] bytes = SerializeObject(u); 133 server.Send(bytes, bytes.Length, ipEndPoint);//給每個用戶發送信息 134 } 135 } 136 //服務器接收所有的消息 137 rtbMessage.Text += "\n" + u.Name + ":" + u.Message; 138 } 139 public void BindListView(string loginName) //有新成員加入的時候就綁定刷新成員列表 140 { 141 flag = true; 142 foreach (ListViewItem items in lvInfo.Items)//循環每個用戶 143 { 144 foreach (ListViewItem item in lvInfo.Items)//給每個用戶發送全部的成員信息 145 { 146 UdpInfo u = new UdpInfo(); 147 u.Name = item.SubItems[0].Text.ToString(); 148 u.IsFist = flag;//添加第一個成員的時候因為要重新初始化客戶端成員列表,而剩下的則不要初始化,所以要設置為true 149 flag = false; 150 u.LoginName = loginName; 151 u.Message = "上線了!"; 152 u.Ip = item.SubItems[1].Text.ToString(); 153 u.Port = item.SubItems[2].Text.ToString(); 154 byte[] bytes = SerializeObject(u); 155 IPAddress ip = IPAddress.Parse(items.SubItems[1].Text); 156 IPEndPoint ipp = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[2].Text));//得到成員的IPEndPoint 157 server.Send(bytes, bytes.Length, ipp); 158 } 159 } 160 } 161 private void 結束程序ToolStripMenuItem_Click(object sender, EventArgs e) 162 { 163 server.Close(); 164 this.Dispose(); 165 Application.Exit(); 166 } 167 168 private void 運行程序ToolStripMenuItem_Click(object sender, EventArgs e) 169 { 170 rtbMessage.Text = "可以發送消息過來了!"; 171 int port = Convert.ToInt32(txtPort.Text); 172 server = new UdpClient(port); 173 ipEndPoint = new IPEndPoint(IPAddress.Any, port); 174 Thread t = new Thread(new ThreadStart(Receices)); 175 t.Start(); 176 } 177 } 178 } View Code?
客戶端(Client)
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 using System.Net; 11 using System.Net.Sockets; 12 using System.Threading; 13 using Model; 14 using System.IO; 15 using System.Runtime.Serialization.Formatters.Binary; 16 17 namespace Client 18 { 19 public partial class forUdp : Form 20 { 21 public forUdp() 22 { 23 InitializeComponent(); 24 } 25 UdpClient client = null; 26 IPEndPoint ipEndPoints = null; 27 private delegate void BindDelegate(UdpInfo u); 28 BindDelegate bd = null; 29 private void forUdp_Load(object sender, EventArgs e) 30 { 31 txtIP.Text = "192.168.1.109"; 32 txtPort.Text = "9018"; 33 txtName.Text = "小哈"; 34 } 35 36 private void 運行程序ToolStripMenuItem_Click(object sender, EventArgs e) 37 { 38 rtbMessage.Text = "可以發送消息過去了!"; 39 int port = Convert.ToInt32(txtPort.Text); 40 ipEndPoints = new IPEndPoint(IPAddress.Parse(txtIP.Text), port); 41 client = new UdpClient(); 42 client.Connect(IPAddress.Parse(txtIP.Text), port);//關聯此IP和端口 43 Send(new UdpInfo() {Name = txtName.Text,Message = "上線了!", Types = 0 }); 44 Thread t = new Thread(new ThreadStart(Receices)); 45 t.Start(); 46 } 47 48 public void Receices()//接收客戶端的消息 49 { 50 while (true) 51 { 52 try 53 { 54 byte[] bytes = client.Receive(ref ipEndPoints); 55 UdpInfo u = DeserializeObject(bytes) as UdpInfo; 56 bd = new BindDelegate(BindRtb); 57 this.Invoke(bd, u); 58 } 59 catch (Exception) 60 { 61 client.Close(); 62 } 63 } 64 } 65 public object DeserializeObject(byte[] pBytes)//反序列化二進制為對象 66 { 67 object newOjb = null; 68 if (pBytes == null) 69 return newOjb; 70 MemoryStream memory = new MemoryStream(pBytes); 71 memory.Position = 0; 72 BinaryFormatter formatter = new BinaryFormatter(); 73 newOjb = formatter.Deserialize(memory); 74 memory.Close(); 75 return newOjb; 76 } 77 public byte[] SerializeObject(object pObj)//序列化對象為二進制的數 78 { 79 if (pObj == null) 80 return null; 81 MemoryStream memory = new MemoryStream(); 82 BinaryFormatter formatter = new BinaryFormatter(); 83 formatter.Serialize(memory, pObj); 84 memory.Position = 0; 85 byte[] read = new byte[memory.Length]; 86 memory.Read(read, 0, read.Length); 87 memory.Close(); 88 return read; 89 } 90 public void BindRtb(UdpInfo u)//將消息添加到消息框中 91 { 92 if (u.Types == 0) 93 { 94 if (u.IsFist == true) 95 lvInfo.Items.Clear(); 96 ListViewItem item = new ListViewItem(u.Name); 97 item.SubItems.Add(u.Ip); 98 item.SubItems.Add(u.Port); 99 lvInfo.Items.Add(item); 100 } 101 else if (u.Types == 3)//如果消息的類型是下線的話 102 { 103 IPEndPoint ipEndPoint = null; 104 foreach (ListViewItem items in lvInfo.Items)//循環每個成員 105 { 106 if (items.SubItems[0].Text.Equals(u.Name)) 107 { 108 IPAddress ip = IPAddress.Parse(items.SubItems[1].Text); 109 ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[2].Text)); 110 lvInfo.Items.Remove(items);//從ListView集合中移除 111 continue; 112 } 113 } 114 } 115 foreach (ListViewItem items in lvInfo.Items) 116 { 117 if(items.SubItems[0].Text.Equals(u.LoginName)) 118 rtbMessage.Text += "\n" + u.Name + ":" + u.Message; 119 } 120 } 121 public void Send(UdpInfo u)//發送消息給服務器 122 { 123 byte[] bytes = SerializeObject(u); 124 client.Send(bytes, bytes.Length); 125 } 126 private void 結束程序ToolStripMenuItem_Click(object sender, EventArgs e) 127 { 128 Send(new UdpInfo() { Name = txtName.Text, Message = "下線了!", Types = 3 }); 129 client.Close(); 130 Application.Exit(); 131 } 132 133 private void btnSend_Click(object sender, EventArgs e) 134 { 135 UdpInfo u = new UdpInfo() { 136 Name = txtName.Text, Message = rtbNews.Text, Types = 1 137 }; 138 if (lvInfo.SelectedItems.Count > 0)//如果有選中的成員的話 139 { 140 u.Types = 2; 141 u.ToName = lvInfo.SelectedItems[0].SubItems[0].Text; 142 } 143 Send(u); 144 lvInfo.SelectedItems.Clear();//清除上一次的痕跡 145 } 146 } 147 } View Code?
轉載于:https://www.cnblogs.com/LiuZhen/p/3503749.html
總結
以上是生活随笔為你收集整理的Udp通讯(零基础)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MongoDB中关于64位整型存储解决方
- 下一篇: C语言二维数组中的指针问题