C# 控制台 socket 实现发送消息-服务端-升级

C# 控制台 socket 实现发送消息-服务端-升级

之前的版本:C# 控制台 socket 实现发送消息-服务端

客户端:c# 控制台 socket 实现发送消息-客户端-升级

命名空间引用

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

全局变量

 		//记录一共有开启了几个端口号,名称是什么
        static List<Mess> portlist = new List<Mess>();
        //记录连接的用户
        static List<NameMess> namelist = new List<NameMess>();
        static Dictionary<int, TcpListener> listeners = new Dictionary<int, TcpListener>();
        static Dictionary<TcpListener, List<TcpClient>> connectedClients = new Dictionary<TcpListener, List<TcpClient>>();
        //端口号
        static string portname = "";

Mian()

 static void Main(string[] args)
        {
            while (true)
            {
                try
                {
                    Console.WriteLine("输入exit,退出");
                    Console.WriteLine("请输入你要开启的端口号:");
                    string port = Console.ReadLine();
                    Console.WriteLine("请输入你开启端口号的名称:");
                    portname = Console.ReadLine();
                    if (port == "exit")
                        return;
                    //多线程的形式开启多个端口
                    Thread receiveThread = new Thread(StartServer);
                    receiveThread.Start(port);
                }
                catch (Exception)
                {

                }
            }
        }

Mess和NameMess

 //存放开启了几个端口
        class Mess
        {
            public string PortName { get; set; }
            public int port { get; set; }
            public TcpListener listener { get; set; }
        }
        //存放连接的用户名称,端口
        class NameMess
        {
            public int ID { get; set; }
            public string PortName { get; set; }
            public int port { get; set; }
        }

StartServer(object obj)方法:开启端口监听端口信息

  //开启端口
        static void StartServer(object obj)
        {
            int port = Convert.ToInt32(obj);
            TcpListener server = new TcpListener(IPAddress.Any, port);
            server.Start();

            Console.WriteLine($"服务器已开启端口:{port}");
            portlist.Add(new Mess { PortName = portname, port = port, listener = server });
            listeners.Add(port, server);

            while (true)
            {
                var client = server.AcceptTcpClient();

                if (!connectedClients.ContainsKey(server))
                {
                    connectedClients.Add(server, new List<TcpClient>());
                }

                // Add the newly accepted client to the list of clients for this listener  
                connectedClients[server].Add(client);

                Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClient));
                clientThread.Start(client);
            }
        }

HandleClient(object obj)方法:监听端口发送的消息,并进行处理,刚刚进入端口,昵称存入,返回ID,后续将消息拼接起来,格式(消息-昵称-:六子-ID-:1)

//监听端口发送的消息
        static void HandleClient(object obj)
        {
            TcpClient tcpclient = (TcpClient)obj;

            NetworkStream stream = tcpclient.GetStream();

            byte[] buffer = new byte[1024];

            int bytesRead;
            
            while (tcpclient.Connected)
            {
                try
                {
                    bytesRead = stream.Read(buffer, 0, buffer.Length);
                    string dataReceived = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                    if (dataReceived.Contains("-portname-"))
                    {
                        int startIndex = 0; // 子串的起始位置为0
                        int endIndex = dataReceived.IndexOf("-");   // 找到第一个 "-" 的位置

                        if (endIndex != -1)
                        {
                            dataReceived = dataReceived.Substring(startIndex, endIndex);
                        }
                        NameMess yh = new NameMess
                        {
                            PortName = dataReceived,
                            port = (tcpclient.Client.LocalEndPoint as IPEndPoint).Port,
                            ID = namelist.Count +1
                        };
                        Console.WriteLine($"欢迎: {dataReceived} 加入 端口号: {(tcpclient.Client.LocalEndPoint as IPEndPoint).Port}");
                        namelist.Add(yh);
                        //返回一个ID
                        byte[] dataToSendBack = Encoding.UTF8.GetBytes(yh.ID + "-yourID-");
                        stream.Write(dataToSendBack, 0, dataToSendBack.Length);
                        continue;
                    }
                    
                    //消息的格式是: 发送的消息-ID-:1
                    int firstDashIndex = dataReceived.IndexOf("-");
                    //发送的消息
                    string firstPart = dataReceived.Substring(0, firstDashIndex);

                    // 截取出第二个部分ID
                    int secondColonIndex = dataReceived.LastIndexOf(":");
                    //携带的ID
                    string lastPart = dataReceived.Substring(secondColonIndex + 1);

                    string name = namelist.Find(u => u.ID == Convert.ToInt32(lastPart)).PortName;
                    dataReceived = firstPart + "-name-:" + name + "-ID-:" + lastPart;
                    if (firstPart == "exit")
                    {
                        Console.WriteLine($"退出: 名字:{name},ID:{lastPart}退出 来自 端口号: {(tcpclient.Client.LocalEndPoint as IPEndPoint).Port}");
                        namelist.Remove(namelist.Find(u => u.ID == Convert.ToInt32(lastPart)));
                    }
                    else
                    {
                        Console.WriteLine($"消息: {dataReceived} 来自 端口号: {(tcpclient.Client.LocalEndPoint as IPEndPoint).Port}");
                    }               
                    // 向同一端口上的所有客户端回传接收到的消息
                    BroadcastMessage(dataReceived, (tcpclient.Client.LocalEndPoint as IPEndPoint).Port);
                }
                catch (Exception ex)
                {

                }
                

            }

            // 关闭连接并清理资源
            tcpclient.Close();
        }

BroadcastMessage(string message, int port)方法:将消息返回给连接一个端口的客户端

        //将消息进行处理,然后返回给客户端
        static void BroadcastMessage(string message, int port)
        {

            foreach (var listener in listeners.Values)
            {
                if ((listener.LocalEndpoint as IPEndPoint).Port == port)
                {
                    foreach (TcpClient connected_client in connectedClients[listener])
                    {
                        try
                        {
                            NetworkStream stream = connected_client.GetStream();
                            byte[] dataToSendBack = Encoding.UTF8.GetBytes(message);
                            stream.Write(dataToSendBack, 0, dataToSendBack.Length);
                        }
                        catch (Exception)
                        {
                        }
                        
                    }
                }
            }
        }

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值