实例介绍
【实例简介】
实现udp群聊
【实例截图】
【核心代码】
using System; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Threading; using CommonUntility; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using System.Runtime.Serialization; using CSharpWin; using System.Drawing.Drawing2D; using System.Text.RegularExpressions; namespace LanChatterApp_ReConstruct_ { public partial class MainFrm : Form { public MainFrm() { InitializeComponent(); } public IPAddress broadIPAddress = IPAddress.Parse("255.255.255.255"); //组播地址 public static int lanPort = 11010; //端口号 public IPEndPoint iep; public UdpClient listenClient = new UdpClient(lanPort); public bool isRun = false; //监听是否启用的标志 public string localIP; //本机ip地址 public string localName; //本机名称 public string remoteIP; //远程主机ip地址 public string remoteName; //远程主机名称 public bool flag = false; //显示图片或者隐藏标志位 public bool emotionFlag = false; #region RichTextBox线程与UI交互委托,用于添加文本内容及上色 /// <summary> /// 添加聊天内容到聊天对话框中 /// </summary> /// <param name="info">消息呈现内容</param> /// <param name="titleOrContentFlag">标记:此信息是信息头还是信息内容,1代表是消息头,2代表是消息体</param> /// <param name="selfOrOthersFlag">标记:此信息是自己发送的还是别人发送的,1代表是自己发送,2代表是别人发送</param> private void AddTextBox(string info, int titleOrContentFlag, int selfOrOthersFlag) { if (1 == titleOrContentFlag) //如果是消息头 { string title = info; if (1 == selfOrOthersFlag) //如果是自己发送 { CommonUntility.RichTextBoxEx.AppendText(rAllContent, title, Color.Green); } else //如果是别人发送 { CommonUntility.RichTextBoxEx.AppendText(rAllContent, title, Color.Blue); } } else if (2 == titleOrContentFlag) //如果是消息体 { string content = info; CommonUntility.RichTextBoxEx.AppendText(rAllContent, content, Color.Black); } } #endregion private void mainFrm_Load(object sender, EventArgs e) { listenClient.EnableBroadcast = true; //允许发送和接受广播 iep = new IPEndPoint(broadIPAddress, lanPort); lstUsers.Items.Add(" Computer IP---Computer Name"); openListeningThread(); //开启监听线程 SendInfoOnline();//发送上线广播信息 LoadingEmotion(); } private void LoadingEmotion() { PictureBox[,] picList = new PictureBox[5,10]; for (int i = 0; i < 5; i ) { for (int j = 0; j < 10; j ) { int emotionSequenceCount = i * 10 j; picList[i,j] = new PictureBox(); picList[i, j].Height = picList[i, j].Width = 24; picList[i, j].Image = Image.FromFile(".\\Face2\\" emotionSequenceCount ".gif"); picList[i, j].Top = i * 24; picList[i, j].Left = j * 24; picList[i, j].Tag = "#(" emotionSequenceCount ")#"; picList[i, j].Parent = panImg; picList[i, j].Click = new EventHandler((sender, e) => { this.rSendContent.AppendText("#(" emotionSequenceCount ")#"); emotionFlag = false; this.panImg.Visible = emotionFlag; }); panImg.Controls.Add(picList[i,j]); } } } /// <summary> /// 开启监听线程 /// </summary> private void openListeningThread() { isRun = true; Thread t = new Thread(new ThreadStart(() => { IPEndPoint ipEnd = new IPEndPoint(broadIPAddress, lanPort); try { while (isRun) { try { byte[] recInfo = listenClient.Receive(ref ipEnd); //接受内容,存储到byte数组中 DealWithAcceptedInfo(recInfo); //处理接收到的数据 } catch (Exception ex) { MessageBox.Show(ex.Message); } } listenClient.Close(); isRun = false; } catch (SocketException se) { throw new Exception(se.Message); } //捕捉试图访问套接字时发生错误。 catch (ObjectDisposedException oe) { throw new Exception(oe.Message); } //捕捉Socket 已关闭 catch (InvalidOperationException pe) { throw new Exception(pe.Message); } //捕捉试图不使用 Blocking 属性更改阻止模式。 catch (Exception ex) { throw new Exception(ex.Message); } })); t.Start(); } /// <summary> /// 方法:处理接到的数据 /// </summary> private void DealWithAcceptedInfo(byte[] recData) { BinaryFormatter formatter = new BinaryFormatter(); MessageModel recvMessage; MemoryStream ms = new MemoryStream(recData); try { recvMessage = (MessageModel)formatter.Deserialize(ms); } catch (SerializationException e) { throw new Exception(e.Message); } switch (recvMessage.Flag) { case "0x00": //用户上线 //这里很关键,当检测到一个新的用户上线,那么我们需要给这个新用户发送自己的机器消息,以便新用户能够自动添加进列表中。 SendInfoOnline(recvMessage.UserIp); if (lstUsers.FindString(recvMessage.UserIp "---" recvMessage.UserName) <= 0) //如果用户不存在 { lstUsers.Invoke((Action)(() => { lstUsers.Items.Add(recvMessage.UserIp "---" recvMessage.UserName); })); lsbLog.Invoke((Action)(() => { lsbLog.Items.Add("User[" recvMessage.UserIp "] is online now!"); })); } break; case "0x01": //用户聊天 rAllContent.Invoke((Action)(() => { rAllContent.AppendText("\r\n"); AddTextBox(recvMessage.UserIp " " DateTime.Now "\r\n", 1, 2); //这是接收到了别人发来的信息 //AddTextBox(recvMessage.MsgContent "\r\n", 2, 2);//将发送的消息添加到窗体中 ParseEmotionInsert.AddContent(recvMessage.MsgContent, rAllContent); rAllContent.AppendText("\r\n"); })); break; case "0x03": //用户下线 if (lstUsers.FindString(recvMessage.UserIp "---" recvMessage.UserName) > 0) //如果用户已经存在 { MessageBox.Show(recvMessage.UserIp "---" recvMessage.UserName); lstUsers.Invoke((Action)(() => { lstUsers.Items.Remove(recvMessage.UserIp "---" recvMessage.UserName); })); lsbLog.Invoke((Action)(() => { lsbLog.Items.Add("User[" recvMessage.UserIp "] is offline now!"); })); } break; default: break; } } /// <summary> /// 广播发送上线消息 /// </summary> private void SendInfoOnline() { localIP = GetLocalIPandName.getLocalIP(); //得到本机ip localName = GetLocalIPandName.getLocalName(); //得到本机的机器名称 MessageModel messageModel = new MessageModel(); messageModel.Flag = "0x00"; messageModel.UserIp = localIP; messageModel.UserName = localName; byte[] messageBytes = Parse.ToByteArray(messageModel); SendInfoByIEP.SendInfoToAll(listenClient, messageBytes, iep);//发送广播上线信息 } /// <summary> /// 向单个ip发送上线消息 /// </summary> /// <param name="remoteip"></param> private void SendInfoOnline(string remoteip) { localIP = GetLocalIPandName.getLocalIP(); //得到本机ip localName = GetLocalIPandName.getLocalName(); //得到本机的机器名称 MessageModel messageModel = new MessageModel(); messageModel.Flag = "0x00"; messageModel.UserIp = localIP; messageModel.UserName = localName; byte[] messageBytes = Parse.ToByteArray(messageModel); IPEndPoint _iep = new IPEndPoint(IPAddress.Parse(remoteip), lanPort); SendInfoByIEP.SendInfoToAll(listenClient, messageBytes, _iep); //发送广播上线信息 } /// <summary> /// 广播发送下线消息 /// </summary> private void SendInfoOffline() { localIP = GetLocalIPandName.getLocalIP(); //得到本机ip localName = GetLocalIPandName.getLocalName(); //得到本机的机器名称 MessageModel messageModel = new MessageModel(); messageModel.Flag = "0x03"; messageModel.UserIp = localIP; messageModel.UserName = localName; byte[] messageBytes = Parse.ToByteArray(messageModel); SendInfoByIEP.SendInfoToAll(listenClient, messageBytes, iep); //发送广播下线信息 } /// <summary> /// 遍历列表,发送消息 /// </summary> private void SendInfo(string data) { try { byte[] _data = Encoding.Default.GetBytes(data); foreach (string s in lstUsers.Items) //遍历列表 { if (s.Contains(".")) //确定包含的是ip地址 { string _ip = s.Split('-')[0]; if (!_ip.Equals(localIP)) //将自身排除在外 { IPEndPoint iepe = new IPEndPoint(IPAddress.Parse(_ip), lanPort); //套接字申明 //这里我们必须申明一个新的实例以避免重复接收问题。(如果利用原来的listenClient实例,将会造成重复接收。) UdpClient udp = new UdpClient(); udp.Send(_data, _data.Length, iepe); //发送 } } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void SendInfo(byte[] data) { try { foreach (string s in lstUsers.Items) //遍历列表 { if (s.Contains(".")) //确定包含的是ip地址 { string _ip = s.Split('-')[0]; if (!_ip.Equals(localIP)) //将自身排除在外 { IPEndPoint iepe = new IPEndPoint(IPAddress.Parse(_ip), lanPort); //套接字申明 //这里我们必须申明一个新的实例以避免重复接收问题。(如果利用原来的listenClient实例,将会造成重复接收。) UdpClient udp = new UdpClient(); udp.Send(data, data.Length, iepe); //发送 } } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// “发送按钮”点击事件 /// </summary> private void btnSend_Click(object sender, EventArgs e) { if (rSendContent.Text == "") { MessageBox.Show("Please fill in some words!","Notification",MessageBoxButtons.OK,MessageBoxIcon.Information); } else { MessageModel messageModel = new MessageModel(); messageModel.Flag = "0x01"; messageModel.UserIp = localIP; messageModel.UserName = localName; messageModel.MsgContent = rSendContent.Text; byte[] byteData = Parse.ToByteArray(messageModel); SendInfo(byteData); //发送消息 rAllContent.AppendText(Environment.NewLine); AddTextBox(localIP " " DateTime.Now "\r\n", 1, 1); //将发送的消息添加到窗体中 ParseEmotionInsert.AddContent(rSendContent.Text,rAllContent); //AddTextBox(rSendContent.Text "\r\n", 2, 1); //将发送的消息添加到窗体中 this.rSendContent.Text = string.Empty; //清空发送内容 } this.rAllContent.ScrollToCaret(); base.Invalidate(true); } /// <summary> /// 点击退出时,发送下线消息 /// </summary> private void mainFrm_FormClosing(object sender, FormClosingEventArgs e) { SendInfoOffline(); Environment.Exit(0); //用户退出 } private void picEmotion_Click(object sender, EventArgs e) { emotionFlag = !emotionFlag; panImg.Visible = emotionFlag; } } }
好例子网口号:伸出你的我的手 — 分享!
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论