博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用C#语言做一个基于UDP的私聊和群聊工具
阅读量:5792 次
发布时间:2019-06-18

本文共 6710 字,大约阅读时间需要 22 分钟。

用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,如需转载请自行联系原作者
你可能感兴趣的文章
Bug多,也别乱来,别被Bug主导了开发
查看>>
sed 替换基础使用
查看>>
高性能的MySQL(5)创建高性能的索引一B-Tree索引
查看>>
oracle备份与恢复--rman
查看>>
图片变形的抗锯齿处理方法
查看>>
Effective C++ Item 32 确保你的 public 继承模子里出来 is-a 关联
查看>>
phpstorm安装laravel-ide-helper实现自动完成、代码提示和跟踪
查看>>
python udp编程实例
查看>>
TortoiseSVN中图标的含义
查看>>
Tasks and Back stack 详解
查看>>
关于EXPORT_SYMBOL的作用浅析
查看>>
成功的背后!(给所有IT人)
查看>>
在SpringMVC利用MockMvc进行单元测试
查看>>
Nagios监控生产环境redis群集服务战
查看>>
Angular - -ngKeydown/ngKeypress/ngKeyup 键盘事件和鼠标事件
查看>>
Android BlueDroid(一):BlueDroid概述
查看>>
Java利用httpasyncclient进行异步HTTP请求
查看>>
宿舍局域网的应用
查看>>
html代码究竟什么用途
查看>>
Hadoop HDFS编程 API入门系列之路径过滤上传多个文件到HDFS(二)
查看>>