TCPClient和TCPListen

时间:2025-03-20 10:20:34

TCPClient

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _2多播客户端
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //连接
        TcpClient client;
        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            button2.Enabled = true;
            button3.Enabled = true;
            //1 创建套接字
            client = new TcpClient();
            try
            {
                client.Connect(new IPEndPoint(IPAddress.Parse("192.168.107.14"), 3000)); //连接目标服务器
            }
            catch (Exception)
            {

                MessageBox.Show("服务已经关闭");
            }

            //接收消息
            StartRecevie(client);

        }
        // 接收消息的方法
        public void StartRecevie(TcpClient s1)
        {

            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        byte[] bs = new byte[1024];//存储接收的消息
                        int length = s1.GetStream().Read(bs,0,bs.Length); //接收消息 返回消息的长度
                        if (length == 0)
                        {
                            //当接收数据长度为0时候,证明服务器断开,
                            richTextBox1.Invoke(new Action(() =>
                            {
                                richTextBox1.AppendText($"服务器已经断开\r\n");
                                button3.Enabled=false;
                                button1.Enabled=true;
                                button2.Enabled = false;

                                //服务器断开 客户端也得断开
                                s1.Close();

                            }));
                            break;
                        }
                        else
                        {
                          string value = Encoding.UTF8.GetString(bs, 0, length);

                            //更新RichTextBox
                            richTextBox1.Invoke(new Action(() =>
                            {
                                richTextBox1.AppendText($"{value}\r\n");
                                richTextBox1.SelectionStart = richTextBox1.Text.Length; //把光标定位到最后字符上
                                richTextBox1.ScrollToCaret();//开始滚动到光标位置
                            }));

                        }
                    }
                    catch (Exception)
                    {
                        s1.Close();
                        richTextBox1.Invoke(new Action(() =>
                        {
                            button3.Enabled = false;
                            button1.Enabled = true;
                            button2.Enabled = false;
                        }));
                        break;
                    }

                }
            });
        }
        // 断开
        private void button2_Click(object sender, EventArgs e)
        {
            button3.Enabled = false;
            button1.Enabled = true;
            button2.Enabled = false;
            client.Close();
        }

         //发消息
        private void button3_Click(object sender, EventArgs e)
        {
            byte[] bs = Encoding.UTF8.GetBytes($"{textBox1.Text}:{textBox2.Text}\r\n");
            //更新自己UI
            richTextBox1.Invoke(new Action(() =>
            {
                richTextBox1.AppendText($"我说:{textBox2.Text}\r\n");
            }));
            if (client != null)
            {
                //发给服务器
                client.GetStream().Write(bs,0,bs.Length);
            }
        }
    }
}

TCPListen

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _1多播服务器器
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
     

        TcpListener listener;//服务器对象
        Dictionary<string,TcpClient> dic = new Dictionary<string, TcpClient>();   //字典,键是ip地址,值对应的客户端对象 

        //打开服务器
        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false; //打开服务器失活
            button2.Enabled = true;// 关闭按钮可以点
            button3.Enabled = true; //发消息按钮管用

            //1 创建套接字
            listener = new TcpListener(new IPEndPoint(IPAddress.Parse("192.168.107.14"), 3000));

            //2 开启监听
            listener.Start(1000);
            //4 开始接收连接
            Connect(listener);

        }
        //连接的方法
        public void Connect(TcpListener soc)
        {
            Task.Run(() =>
            {
                while (true)
                {

                    try
                    {
                        TcpClient clinet =  soc.AcceptTcpClient();// 接收客户端
                        dic.Add(clinet.Client.RemoteEndPoint.ToString(), clinet);//保存所有的客户端
                        richTextBox1.Invoke(new Action(() =>
                        {
                            richTextBox1.AppendText($"{clinet.Client.RemoteEndPoint.ToString()}已经连接\r\n");
                        }));

                        //5 接收客户端发送的消息
                        ReceiveMsg(clinet);
                    }
                    catch (Exception ex)
                    {
                        if (listener != null)
                        {
                            // 服务器没开启
                            listener.Stop();// 关闭服务器
                            Console.WriteLine("服务器断开");
                        }                    
                        break; //跳出while循环
                        
                    }
                }

            });
        }

        //接收客户端发送的消息
        public void ReceiveMsg(TcpClient s1)
        {
            string ip = s1.Client.RemoteEndPoint.ToString();//取出客户端ip和端口
            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        byte[] bs = new byte[1024];//存储接收的消息
                        int length =  s1.GetStream().Read(bs,0,bs.Length); //接收消息 返回消息的长度
                        if(length==0)
                        {
                            //当接收数据长度为0时候,证明客户端会断开,客户端断开的时候会给服务器发一个空消息
                            //需要把这个断开的客户端给移除
                            dic.Remove(ip);

                            richTextBox1.Invoke(new Action(() =>
                            {
                                richTextBox1.AppendText($"{ip}已经断开接\r\n");
                            }));
                            break;
                        }
                        else
                        {
                            //接收到消息 转发给除了自己以外的所有的人
                            string value = Encoding.UTF8.GetString(bs, 0, length);

                            //转发给其他客户端
                            foreach (var item in dic) // 遍历字典
                            {
                                if (item.Key != ip)// 不是自己的情况下
                                {
                                    item.Value.GetStream().Write(bs,0,bs.Length);
                                }
                            }

                            //更新RichTextBox
                            richTextBox1.Invoke(new Action(() =>
                            {
                                richTextBox1.AppendText($"{ip}发来消息:{value}\r\n");
                            }));

                        }
                    }
                    catch (Exception)
                    {
                        //客户端断开
                        dic.Remove(ip);
                        richTextBox1.Invoke(new Action(() =>
                        {
                            richTextBox1.AppendText($"{ip}已经断开接\r\n");
                        }));
                        break;
                    }

                }
            });
        }
        //服务器关闭
        private void button2_Click(object sender, EventArgs e)
        {
            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false; //发消息按钮不管用
            foreach (var item in dic)
            {
                TcpClient s1 = item.Value;
                s1.Close(); //关闭客户端
            }
           dic.Clear();//清空字典
           listener.Stop();//关闭服务器
            listener = null;//服务器对象置为空
        }

        //服务器群发送消息
        private void button3_Click(object sender, EventArgs e)
        {
            byte[] bs = Encoding.UTF8.GetBytes(textBox1.Text);
            foreach (var item in dic)
            {
                item.Value.GetStream().Write( bs,0,bs.Length);
            }
        }
    }
}