zoukankan      html  css  js  c++  java
  • C#使用Tcp/Udp协议

    所使用的:多线程 委托 Socket 键值队

    个人跟着视频做的一个小练习,有兴趣的可以去看一下对于初学者来讲是比较有帮助的

    连接:https://www.bilibili.com/video/BV1bZ4y1W74q?p=3&t=358

    废话不多说上代码  综合视频中的理解 有什么不对的地方希望大神指点一下 

     public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                myAddOnlieDelegate = AddOnlie;
                myAddTextDelegate = AddTexr;
            }
    
            private void AddTexr(string str)
            {
                //将文字追加到文本中
                txt_centext.AppendText(str);
            }
    
            /// <summary>
            /// 委托方法
            /// </summary>
            /// <param name="str"></param>
            /// <param name="bl"></param>
            private void AddOnlie(string str, bool bl)
            {
                if (bl)
                {
                    //如果是true的话对listbox.Item进行一个添加
                    listOne.Items.Add(str);
                }
                else
                {
                    //反之删除
                    listOne.Items.Remove(str);
                }
            }
    
    
    
            //实例化Socket
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //接口
            Thread thread = null;
            //键值队
            Dictionary<string, Socket> Dic = new Dictionary<string, Socket>();
            //委托
            delegate void MyAddOnlieDelegate(string  str,bool bl);
            delegate void MyAddTextDelegate(string str);
            MyAddOnlieDelegate myAddOnlieDelegate;
            MyAddTextDelegate myAddTextDelegate;
            private void button1_Click(object sender, EventArgs e)
            {
                #region 第一步获取IP和端口进行相互通信
                //获取IP
                IPAddress IP = IPAddress.Parse(txt_IP.Text.Trim());
                //把IP和端口号放在IPEndPoint中
                IPEndPoint IEnd = new IPEndPoint(IP,int.Parse(txt_port.Text.Trim()));
                try
                {
                    //和socket进行关联
                    socket.Bind(IEnd);
                    MessageBox.Show("服务器开启成功!");
                }
                catch (Exception ex)
                {
                    //失败了直接return出去
                    MessageBox.Show("服务器开启失败" + ex.Message);
                    return;
                }
                //socket可以对多少个客户端进行监视
                socket.Listen(10);
                #endregion
                #region 第二部开启多线程
                //开始进行多线程操作 开始执行此线程时要调用的方法的
                thread = new Thread(ListenConnectingl);
                //此线程则为后台线程
                thread.IsBackground = true;
                //启动线程
                thread.Start();
                //连接到服务器后把按钮禁用掉
                button1.Enabled = false;
                #endregion
            }
    
            /// <summary>
            /// 正在进行的后台线程的方法
            /// </summary>
            private void ListenConnectingl()
            {
                //线程使用时进行循环
                while (true)
                {
                    //创建一个新的Socket  列:如果有一个新的客户端来连接服务器给他一个Socket
                    Socket socketConnect = socket.Accept();
                    //把谁连接的客户端给到skt中 字符串
                    string skt = socketConnect.RemoteEndPoint.ToString();
                    Dic.Add(skt, socketConnect);
                    Invoke(myAddOnlieDelegate, skt, true);
                    //更新设备列表  需要接受来自不同客户端的消息 接着在开一个线程  
                    Thread thr = new Thread(ReceiveMsg);
                    thr.IsBackground = true;
                    thr.Start(socketConnect);
                    
                }
            }
            /// <summary>
            /// 开的发送接受的线程 直接从上面传递过来参数 vs中没显示用什么类型的  视频中vs显示可以使用object类型 所有类型的基类来展示  带参的
            /// </summary>
            /// <param name="socketConnect"></param>
            private void ReceiveMsg(object socketConnect)
            {
                //as:转换强转  把object转换成Socket
                Socket so = socketConnect as Socket;
                while (true)
                {
                    byte[] arr = new byte[1024 * 1024 * 2];
                    //定义一个变量
                    int Length = -1;
                    //try
                    //{
                        //Receive返回的是一个int类型的数据 如果没有的直接关闭掉
                        Length = so.Receive(arr);
                    //}
                    //catch (Exception)
                    //{
    
                    //    //如果字节数没有的话把他移除掉
                    //    string str = so.RemoteEndPoint.ToString();
                    //    Dic.Remove(str);
                    //    //引用的委托
                    //    //Invoke(myAddTextDelegate, str+"下线了");
                    //    Invoke(myAddOnlieDelegate, str, false);
                    //    break;
                    //}
                   
                    //加的if判断条件
                    if (Length == 0)
                    {
                        //如果字节数没有的话把他移除掉
                        string str = so.RemoteEndPoint.ToString();
                        Dic.Remove(str);
                        //引用的委托
                        Invoke(myAddOnlieDelegate, str, false);
                        break;
                    }
                    else
                    {
                        //如果成功把接受的byte转换成string
                        string str = Encoding.UTF8.GetString(arr);
                        Invoke(myAddTextDelegate, str+Environment.NewLine);
    
                    } 
                }
            }
            /// <summary>
            /// 发送消息   只能发送字节流
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void button2_Click(object sender, EventArgs e)
            {
                //要发送的文字
                string str=txt_gocentext.Text.Trim();
                byte[] bt = Encoding.UTF8.GetBytes(str);
                ///
                if (listOne.SelectedItems.Count == 0)
                {
                    MessageBox.Show("请选择要发送的对象");
                }
                else
                {
                    foreach (String item in listOne.SelectedItems)
                    {
                        //send发送到指定的socket中
                        Dic[item].Send(bt);
                        string Msg = "[发送]" + item + " " + str+ System.Environment.NewLine;
                        //使用一个委托直接写入
                        Invoke(myAddTextDelegate, Msg+ Environment.NewLine);
                    }
                }
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                Form2 form2 = new Form2();
                form2.Show();
            }
        }
    

      

  • 相关阅读:
    关于PHP高并发抢购系统设计
    阿里云服务器带宽跑满怎么办
    DedeCMS数据负载性能优化方案简单几招让你提速N倍
    linux===启动sdk manager下载配置sdk的时候报错的解决办法
    linux===linux后台运行和关闭、查看后台任务(转)
    自动化测试===热门开源自动化测试框架
    python实战===图片转换为字符的源码(转)
    移动端测试===安卓设备共享程序-发布版本“share device”
    MACACA===gradle下载和安装
    jython
  • 原文地址:https://www.cnblogs.com/xunmengrenli/p/13377971.html
Copyright © 2011-2022 走看看