zoukankan      html  css  js  c++  java
  • C#- Socket实现服务器与多个客户端通信

      因为工作需要,做一个C#的小DEMO来调试程序,好久没有写过SOCKET在网上找到一篇,代码看起来比较清晰明了。于是转载记录在这里,原文网址是:https://blog.csdn.net/luming666/article/details/79125453

      Server端代码:

    class Program
    {
        //创建一个和客户端通信的套接字
        static Socket SocketWatch = null;
        //定义一个集合,存储客户端信息
        static Dictionary<string, Socket> ClientConnectionItems = new Dictionary<string, Socket> { };
     
        static void Main(string[] args)
        {
            //端口号(用来监听的)
            int port = 6000;
     
            //string host = "127.0.0.1";
            //IPAddress ip = IPAddress.Parse(host);
            IPAddress ip = IPAddress.Any;
     
            //将IP地址和端口号绑定到网络节点point上  
            IPEndPoint ipe = new IPEndPoint(ip, port);
     
            //定义一个套接字用于监听客户端发来的消息,包含三个参数(IP4寻址协议,流式连接,Tcp协议)  
            SocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //监听绑定的网络节点  
            SocketWatch.Bind(ipe);
            //将套接字的监听队列长度限制为20  
            SocketWatch.Listen(20);
     
     
            //负责监听客户端的线程:创建一个监听线程  
            Thread threadwatch = new Thread(WatchConnecting);
            //将窗体线程设置为与后台同步,随着主线程结束而结束  
            threadwatch.IsBackground = true;
            //启动线程     
            threadwatch.Start();
     
            Console.WriteLine("开启监听......");
            Console.WriteLine("点击输入任意数据回车退出程序......");
            Console.ReadKey();
     
            SocketWatch.Close();
     
            //Socket serverSocket = null;
     
            //int i=1;
            //while (true)
            //{
            //    //receive message
            //    serverSocket = SocketWatch.Accept();
            //    Console.WriteLine("连接已经建立!");
            //    string recStr = "";
            //    byte[] recByte = new byte[4096];
            //    int bytes = serverSocket.Receive(recByte, recByte.Length, 0);
            //    //recStr += Encoding.ASCII.GetString(recByte, 0, bytes);
            //    recStr += Encoding.GetEncoding("utf-8").GetString(recByte, 0, bytes);
     
            //    //send message
            //    Console.WriteLine(recStr);
     
            //    Console.Write("请输入内容:");
            //    string sendStr = Console.ReadLine();
     
            //    //byte[] sendByte = Encoding.ASCII.GetBytes(sendStr);
            //    byte[] sendByte = Encoding.GetEncoding("utf-8").GetBytes(sendStr);
     
            //    //Thread.Sleep(4000);
     
            //    serverSocket.Send(sendByte, sendByte.Length, 0);
            //    serverSocket.Close();
            //    if (i >= 100)
            //    {
            //        break;
            //    }
            //    i++;
            //}
                
            //sSocket.Close();
            //Console.WriteLine("连接关闭!");
     
     
            //Console.ReadLine();
        }
     
        //监听客户端发来的请求  
        static void WatchConnecting()
        {
            Socket connection = null;
     
            //持续不断监听客户端发来的请求     
            while (true)
            {
                try
                {
                    connection = SocketWatch.Accept();
                }
                catch (Exception ex)
                {
                    //提示套接字监听异常     
                    Console.WriteLine(ex.Message);
                    break;
                }
     
                //客户端网络结点号  
                string remoteEndPoint = connection.RemoteEndPoint.ToString();
                //添加客户端信息  
                ClientConnectionItems.Add(remoteEndPoint, connection);
                //显示与客户端连接情况
                Console.WriteLine("
    [客户端"" + remoteEndPoint + ""建立连接成功! 客户端数量:" + ClientConnectionItems .Count+ "]");
     
                //获取客户端的IP和端口号  
                IPAddress clientIP = (connection.RemoteEndPoint as IPEndPoint).Address;
                int clientPort = (connection.RemoteEndPoint as IPEndPoint).Port;
     
                //让客户显示"连接成功的"的信息  
                string sendmsg = "[" + "本地IP:" + clientIP + " 本地端口:" + clientPort.ToString() + " 连接服务端成功!]";
                byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendmsg);
                connection.Send(arrSendMsg);
     
                //创建一个通信线程      
                Thread thread = new Thread(recv);
                //设置为后台线程,随着主线程退出而退出 
                thread.IsBackground = true;
                //启动线程     
                thread.Start(connection);
            }
        }
     
        /// <summary>
        /// 接收客户端发来的信息,客户端套接字对象
        /// </summary>
        /// <param name="socketclientpara"></param>    
        static void recv(object socketclientpara)
        {
            Socket socketServer = socketclientpara as Socket;
     
            while (true)
            {
                //创建一个内存缓冲区,其大小为1024*1024字节  即1M     
                byte[] arrServerRecMsg = new byte[1024 * 1024];
                //将接收到的信息存入到内存缓冲区,并返回其字节数组的长度    
                try
                {
                    int length = socketServer.Receive(arrServerRecMsg);
     
                    //将机器接受到的字节数组转换为人可以读懂的字符串     
                    string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
     
                    //将发送的字符串信息附加到文本框txtMsg上     
                    Console.WriteLine("
    [客户端:" + socketServer.RemoteEndPoint + " 时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")+ "]
    " + strSRecMsg);
     
                    //Thread.Sleep(3000);
                    //socketServer.Send(Encoding.UTF8.GetBytes("[" + socketServer.RemoteEndPoint + "]:"+strSRecMsg));
                    //发送客户端数据
                    if (ClientConnectionItems.Count > 0)
                    {
                        foreach (var socketTemp in ClientConnectionItems)
                        {
                            socketTemp.Value.Send(Encoding.UTF8.GetBytes("[" + socketServer.RemoteEndPoint + "]:" + strSRecMsg));
                        }
                    }
                }
                catch (Exception)
                {
                    ClientConnectionItems.Remove(socketServer.RemoteEndPoint.ToString());
                    //提示套接字监听异常  
                    Console.WriteLine("
    [客户端"" + socketServer.RemoteEndPoint + ""已经中断连接! 客户端数量:" + ClientConnectionItems.Count+"]");
                    //关闭之前accept出来的和客户端进行通信的套接字 
                    socketServer.Close();
                    break;
                }
            }
        }
    }
    

      Client端代码:

    class Program
    {
        //创建1个客户端套接字和1个负责监听服务端请求的线程  
        static Thread ThreadClient = null;
        static Socket SocketClient = null;
     
        static void Main(string[] args)
        {
            try
            {
                int port = 6000;
                string host = "127.0.0.1";//服务器端ip地址
     
                IPAddress ip = IPAddress.Parse(host);
                IPEndPoint ipe = new IPEndPoint(ip, port);
     
                //定义一个套接字监听  
                SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     
                try
                {
                    //客户端套接字连接到网络节点上,用的是Connect  
                    SocketClient.Connect(ipe);
                }
                catch (Exception)
                {
                    Console.WriteLine("连接失败!
    ");
                    Console.ReadLine();
                    return;
                }
     
                ThreadClient = new Thread(Recv);
                ThreadClient.IsBackground = true;
                ThreadClient.Start();
     
                Thread.Sleep(1000);
                Console.WriteLine("请输入内容<按Enter键发送>:
    ");
                while(true)
                {
                    string sendStr = Console.ReadLine();
                    ClientSendMsg(sendStr);
                }
     
                //int i = 1;
                //while (true)
                //{
                //    Console.Write("请输入内容:");
                //    string sendStr = Console.ReadLine();
     
                //    Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //    clientSocket.Connect(ipe);
                //    //send message
                //    //byte[] sendBytes = Encoding.ASCII.GetBytes(sendStr);
                //    byte[] sendBytes = Encoding.GetEncoding("utf-8").GetBytes(sendStr);
     
                //    //Thread.Sleep(4000);
     
                //    clientSocket.Send(sendBytes);
     
                //    //receive message
                //    string recStr = ""; 
                //    byte[] recBytes = new byte[4096];
                //    int bytes = clientSocket.Receive(recBytes, recBytes.Length, 0);
                //    //recStr += Encoding.ASCII.GetString(recBytes, 0, bytes);
                //    recStr += Encoding.GetEncoding("utf-8").GetString(recBytes, 0, bytes);
                //    Console.WriteLine(recStr);
     
                //    clientSocket.Close();
                //    if (i >= 100)
                //    {
                //        break;
                //    }
                //    i++;
                //}
                    
                //Console.ReadLine();
                //return;
     
                //string result = String.Empty;
     
            }
            catch (Exception ex) 
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }
     
        //接收服务端发来信息的方法    
        public static void Recv()
        {
                int x = 0;
            //持续监听服务端发来的消息 
            while (true)
            {
                try
                {
                    //定义一个1M的内存缓冲区,用于临时性存储接收到的消息  
                    byte[] arrRecvmsg = new byte[1024 * 1024];
     
                    //将客户端套接字接收到的数据存入内存缓冲区,并获取长度  
                    int length = SocketClient.Receive(arrRecvmsg);
     
                    //将套接字获取到的字符数组转换为人可以看懂的字符串  
                    string strRevMsg = Encoding.UTF8.GetString(arrRecvmsg, 0, length);
                    if (x == 1)
                    {
                        Console.WriteLine("
    服务器:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "
    " + strRevMsg+"
    ");
                            
                    }
                    else
                    {
                        Console.WriteLine(strRevMsg + "
    ");
                        x = 1;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("远程服务器已经中断连接!" + ex.Message + "
    ");
                    break;
                }
            }
        }
     
        //发送字符信息到服务端的方法  
        public static void ClientSendMsg(string sendMsg)
        {
            //将输入的内容字符串转换为机器可以识别的字节数组     
            byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);
            //调用客户端套接字发送字节数组     
            SocketClient.Send(arrClientSendMsg);
        }    
    }

    测试结果:
    server端:

    client端:

    代码下载地址:http://download.csdn.net/download/luming666/10217302

  • 相关阅读:
    我为什么写博客
    Jquery选中行实现行中的Checkbox的选中与取消选中
    jquery中attr和prop的区别
    如何将.il、.res文件封装成dll文件
    修改VS2010生成的dll文件中的内容
    asp.net mvc4中自定义404页面
    asp.net EF6.0中出现未找到具有固定名称“System.Data.SqlClient”的 ADO.NET提供程序的实体框架提供程序解决办法
    ASP.NET中JSON的序列化和反序列化(转)
     WPF 控件总结
    C语言基础:二维数组 分类: iOS学习 c语言基础 2015-06-10 21:42 16人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/cxeye/p/13607357.html
Copyright © 2011-2022 走看看