用C#语言做一个基于UDP的私聊和群聊工具

简介:
用C#语言做一个基于UDP的私聊和群聊工具
 
 
这个工具的最终界面:
 
测试界面:
 
 
 
 
 
 
 
代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Collections;
namespace chat
{
    public partial class Form1 : Form
    {
        private bool isExit = false;
        private bool isShow = true;
        private bool m_bFlag;
         
        NotifyIcon myNotifyIcon;
        delegate void AppendStringCallback(string text);
        AppendStringCallback appendStringCallback;
        
        
        private UdpClient udpClient;
        private delegate void SetComboBoxCallback(string str);
        SetComboBoxCallback set_combobox_callback;
        public Form1()
        {
            InitializeComponent();
             appendStringCallback = new AppendStringCallback(AppendString);
             set_combobox_callback = new SetComboBoxCallback(SetComboBox);
             try
             {
                 m_Icon1 = new Icon("20005.ico");//导入图标文件 
                 m_Icon2 = new Icon("20060.ico");
             }
             catch (Exception e)
             {
                 MessageBox.Show("Error " + e.Message, "Animate Tray - Error");
               
             }
             m_bFlag = true;

         }
        #region connect_and_stop
        private void btnChat_Click(object sender, EventArgs e)
        {
            Thread receiveThread = new Thread(new ThreadStart(ReceiveData));
            //将线程设为后台运行
            receiveThread.IsBackground = true;
            receiveThread.Start();
            btnChat.Enabled = false;
            btnStop.Enabled = true;
            txbSend.Enabled = true;
        }
        private void btnStop_Click(object sender, EventArgs e)
        {
            udpClient.Close();
            btnChat.Enabled = true;
            btnStop.Enabled = false;
            txbSend.Enabled = false;
        }
        #endregion
        #region Receive_events
        private void ReceiveData()
        {
            IsValidPort(txtPort.Text);
            
            try
            {
                //使用的接收端口号
                int port = int.Parse(txtPort.Text);
                udpClient = new UdpClient(port);
                //必须使用组播的地址范围内的地址
                IPAddress groupIP = IPAddress.Parse(groupIPaddress.Text);
                udpClient.JoinMulticastGroup(groupIP, 50);
               
            }
            catch
            { 
            
            }
            IPEndPoint remote = null;
            //接收从远程主机发送过来的信息
            while (true)
            {
                try
                {
                    //关闭udpClient时此句会产生异常
                    byte[] bytes = udpClient.Receive(ref remote);
                  string address = remote.ToString();
                    int atIndex = address.IndexOf(":");
                    string memberaddress = address.Substring(0, atIndex);
                    cbxChoose.Invoke(set_combobox_callback, memberaddress);
                    string str = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
                    AppendString(string.Format("来自{0}:{1}", remote, str));
                  
                }
                catch
                {
                    //退出循环,结束线程
                    break;
                }
            }
        }
        #endregion
        #region Send_events
        private void send(string IPadd, string Port)
        {

         UdpClient myUdpClient = new UdpClient();
         try
           {
            IPAddress add = IPAddress.Parse(IPadd);
            int port = int.Parse(Port);
            IPEndPoint iep = new IPEndPoint(add, port);
           
            int retry = 0;
            while (true)
            {
                try
                {
                    //将发送内容转换为字节数组
                    byte[] bytes = Encoding.UTF8.GetBytes(txbSend.Text);
                    //向子网发送信息
                    myUdpClient.Send(bytes, bytes.Length, iep);
                    AppendString(string.Format("发给{0}:{1}", iep, txbSend.Text));
                    txbSend.Clear();
                    txbSend.Focus();
                    break;
                }
                catch
                {
                    if (retry < 3)
                    {
                        retry++; continue;
                    }
                    else
                    {
                        MessageBox.Show("发送失败!");
                    }
                }
                finally
                {
                    myUdpClient.Close();
                }
            }
           }
         catch
           {
            }
               
        }
        private void btnSend_Click(object sender, EventArgs e)
        {
            //检测发送框的信息是不是为空 
            if (txbSend.Text=="")
            {
                MessageBox.Show("发送信息不能为空");
                return;
            }
            IsValidPort(txtPort.Text);
            
            UdpClient myUdpClient = new UdpClient();
            
            int index = cbxChoose.SelectedIndex;
            if (txtIPaddree.Text == ""&& (index==0 || index==-1))
            {
                IsValidIP(groupIPaddress.Text);
               
                try
                {
                 

                   IPAddress add = IPAddress.Parse(groupIPaddress.Text);
                   int port = Convert.ToInt32(txtPort.Text);
                    IPEndPoint iep = new IPEndPoint(add, port);
                   //将发送内容转换为字节数组
                   byte[] bytes = Encoding.UTF8.GetBytes(txbSend.Text);
                   //向子网发送信息
                   myUdpClient.Send(bytes, bytes.Length, iep);
                   txbSend.Clear();
                   txbSend.Focus();
                   
                }
                catch 
                {
                    MessageBox.Show( "发送失败");
                }
                finally
                {
                    myUdpClient.Close();
                }
            }
            else if (index == 0 || index == -1)
            {
                IsValidIP(txtIPaddree.Text);
            
                    send(txtIPaddree.Text, txtPort.Text);
               
            }
            else 
            {
                
                send(cbxChoose.Text, txtPort.Text);
            }
 
        }

        #endregion
        #region IsValid_field
        //检测输入对方IP有没有效
        private void IsValidIP(string str)
        {
            IPAddress ip;
            if (!IPAddress.TryParse(str, out ip))
            {
                MessageBox.Show("非法IP地址");
              
                return;
            }
        }
        //检测端口号有没有效
        private void IsValidPort(string str)
        {
            int isPort;
 
            if (txtPort.Text == "")
            {
                MessageBox.Show("端口号不能为空");
                return;
            }
            else if (!int.TryParse(str, out isPort))
            {
                MessageBox.Show("端口号无效");
                return;
            }
            else if ((isPort < 1024) || (isPort > 65335))
            {
                MessageBox.Show("端口号应该大于或等于1024,小于或等于65535");
                return;
            }
        }
        #endregion
        #region tray_field
        private void Form1_Load(object sender, EventArgs e)
        {
            btnChat.Enabled = true;
            btnStop.Enabled = false;
            txbSend.Enabled = false;
            cbxChoose.SelectedIndex = 0;
            //在当前窗体的容器中创建托盘图标NotifyIcon的实例
            myNotifyIcon = new NotifyIcon(this.components);
            //指定托盘图标
            myNotifyIcon.Icon = new Icon("1644.ico");
            //鼠标悬停在托盘图标上方时显示的内容
            myNotifyIcon.Text = "我的聊天器";
            //设置关联的上下文菜单
            myNotifyIcon.ContextMenuStrip = this.contextMenuStrip1;
            //显示托盘图标
            myNotifyIcon.Visible = true;
            //添加用户双击任务栏中的托盘图标时触发的事件
            myNotifyIcon.DoubleClick += new EventHandler(myNotifyIcon_DoubleClick);
        }
        void myNotifyIcon_DoubleClick(object sender, EventArgs e)
        {
            if (isShow)
            {
                this.Hide();
                isShow = false;
            }
            else
            {
                this.Show();
                isShow = true;
            }
        }
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (isExit == false)
            {
                //取消关闭窗体事件
                e.Cancel = true;
                //隐藏窗体
                this.Hide();
            }
            else
            {
                udpClient.Close();
            }
        }
        private void 显示窗口toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            this.Show();
        }
        private void 退出程序toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            isExit = true;
            Application.Exit();
        }
        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            if (isShow)
            {
                this.Hide();
                isShow = false;
            }
            else
            {
                this.Show();
                isShow = true;
            }
        }
        private Icon m_Icon1;
        private Icon m_Icon2;
        private void 打开计时器ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tmIcon.Start();
        }
        private void 停止计时器ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tmIcon.Stop();
        }
        private void tmIcon_Tick(object sender, EventArgs e)
        {
            if (m_Icon1 != null && m_Icon2 != null) //如果两个图标文件都被正确载入 
            {
                //只要tmIcon被启动,则在两个图标之间不断进行选择变换,实现动画效果 
                if (m_bFlag == true)
                {
                    notifyIcon1.Icon = m_Icon2;
                    m_bFlag = false;
                }
                else
                {
                    notifyIcon1.Icon = m_Icon1;
                    m_bFlag = true;
                }
            }
        }
        #endregion
        #region control_delegate_method
        private void AppendString(string text)
        {
            if (rtbMessage.InvokeRequired)
            {
                rtbMessage.Invoke(appendStringCallback, text);
            }
            else
            {
                rtbMessage.AppendText(text + "\r\n");
            }
        }
        private void SetComboBox(string str)
        {
            //去除掉cbxChoose控件选项的重复内容
            cbxChoose.Items.Add(str);
            for (int i = 0; i < this.cbxChoose.Items.Count; i++) 
            { 
                for (int j = 1; j < this.cbxChoose.Items.Count - 1; j++)
                { 
                    if (this.cbxChoose.Items[i].ToString() == this.cbxChoose.Items[j].ToString())
                    { this.cbxChoose.Items.Remove(this.cbxChoose.Items[j]);
                    } 
                } 
            }
        }
        #endregion
        private void button1_Click(object sender, EventArgs e)
        {
            rtbMessage.Clear();
        }
 
 
 
 

    }
}


本文转自gauyanm 51CTO博客,原文链接:http://blog.51cto.com/gauyanm/343689,如需转载请自行联系原作者
相关文章
|
2月前
|
自然语言处理 C# Windows
C#开源免费的Windows右键菜单管理工具
C#开源免费的Windows右键菜单管理工具
|
5月前
|
缓存 开发框架 监控
一个C#开发的开源的快速启动工具
一个C#开发的开源的快速启动工具
43 0
|
1月前
|
数据挖掘 C# 开发工具
采用C#语言开发的全套医院体检系统PEIS源码功能介绍
体检系统,是专为体检中心/医院体检科等体检机构,专门开发的全流程管理系统,通过软件实现检测仪器数据自动提取,内置多级医生工作台,细化工作将体检检查结果汇总,生成体检报告登记到计算机系统中。通过软件系统进行数据分析统计与评判以及建立体检相关的体检档案。从而实现体检流程的信息化,提高工作效率,减少手动结果录入的一些常犯错误。 在实际应用中,医院体检系统能够解决传统体检中手工操作带来的问题,如工作量大、效率低下、易漏检、重检或错检等。通过与医院信息系统(如HIS、LIS、PACS等)的连接,系统能够满足体检中心的日常工作流程,提供更好的管理、统计和查询分析功能。同时,基于网络基础的系统可以在网上传输
24 1
|
3月前
|
存储 安全 算法
C# 泛型:类型参数化的强大工具
【1月更文挑战第7天】本文将深入探讨C#语言中的泛型编程,包括泛型的定义、用途、优势以及实际应用。通过类型参数化,泛型允许开发者编写更加灵活且可重用的代码,同时提高程序的类型安全性和性能。本文将通过示例代码和详细解释,帮助读者更好地理解泛型在C#中的重要性和实用性。
|
4月前
|
JSON C# 图形学
【Unity 3D】利用C#、Unity和Socket实现简单的在线聊天室工具(附源码 简单易懂)
【Unity 3D】利用C#、Unity和Socket实现简单的在线聊天室工具(附源码 简单易懂)
48 0
|
4月前
|
C#
C# 高级语言的 “进制转换”
C# 高级语言的 “进制转换”
|
5月前
|
开发框架 JavaScript Java
推荐一个日历转换开源工具库,支持C#、Java、PHP等主流的语言
推荐一个日历转换开源工具库,支持C#、Java、PHP等主流的语言
42 0
|
6月前
|
安全 Java C#
C#语言基础知识
C#语言基础知识
|
7月前
|
缓存 网络协议 C#
C#开源、功能强大、免费的Windows系统优化工具 - Optimizer
C#开源、功能强大、免费的Windows系统优化工具 - Optimizer