C#服务器客户端模型以及网络聊天室实例

时间:2019-04-03
本文章向大家介绍C#服务器客户端模型以及网络聊天室实例,主要包括C#服务器客户端模型以及网络聊天室实例使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

实现了简单的聊天室功能,多个客户端连接一个服务器,客户端和服务器双向收发消息,服务器向所有用户广播消息

服务器:

主函数文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SeverTest
{
    class Program
    {
        static void Main(string[] args)
        {
            SeverControl sever = new SeverControl();
            sever.start();
            Console.ReadLine();
        }
    }
}

SeverControl类文件

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

namespace SeverTest
{
    class SeverControl
    {
        private Socket severSocket;
        private List<Socket> clientList;//创建一个socket集合来保存正在连接的客户端
        public SeverControl()
        {
            severSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            clientList = new List<Socket>();
        }
        public void start()
        {
            severSocket.Bind(new IPEndPoint(IPAddress.Any,12581));//设置允许访问ip和端口
            severSocket.Listen(10);//开始监听端口
            Console.WriteLine("服务器启动");

            Thread acceptThread = new Thread(Accept);//新建一个线程来接受客户端连接
            acceptThread.IsBackground = true;
            acceptThread.Start();

        }
        public void Accept()
        {
            Socket client = severSocket.Accept();
            IPEndPoint point = client.RemoteEndPoint as IPEndPoint;//RemoteEndPoint必须强制转成IPEndPoint
            Console.WriteLine(point.Address + "[" + point.Port + "]" + " 连接成功");
            clientList.Add(client);//将连接保存到集合

            Thread receiveThread = new Thread(Receive);//新建一个线程来接收客户端传来的数据
            receiveThread.IsBackground = true;
            receiveThread.Start(client);
            Accept();
        }
        public void Receive(Object obj)//带参数线程函数形传参必须是Object
        {
            byte[] s = new byte[1024];
            Socket client = obj as Socket;
            IPEndPoint point = client.RemoteEndPoint as IPEndPoint;
            //clint.receive方法会挂起线程,当客户端断开连接时会抛出异常
            try { 
                int msglen = client.Receive(s);//获得客户端传来的数据,以byte数组形式传给s,返回字符串长度
                string str = point.Address + " 说: " + Encoding.UTF8.GetString(s, 0, msglen);
                Console.WriteLine(str);
                BroadCast(client, str);//向所有连接的客户端进行广播
                Receive(client);
            }
            catch
            {
                Console.WriteLine(point.Address+"["+point.Port+"]"+"断开");
                clientList.Remove(client);//将连接从集合移除
            }
        }
        private void BroadCast(Socket clientother,string str)
        {
            foreach(var client in clientList)
            {
                if (client == clientother)
                {
                    //本人发出,不回应
                }
                else
                {
                    client.Send(Encoding.UTF8.GetBytes(str));
                }
            }
        }
    }
}

客户端

主函数文件

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

namespace ClientTest
{
    class Program
    {
        static void Main(string[] args)
        {
            ClientControl client = new ClientControl();
            client.connect("127.0.0.1",12581);
            client.send();
        }
    }
}

ClientControl类文件

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

namespace ClientTest
{
    public class ClientControl
    {
        private Socket clientSocket;
        public ClientControl()
        {
            clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        }
        public void connect(string ip,int port)
        {
            clientSocket.Connect(ip,port);
            Console.WriteLine("连接服务器成功");
            Console.WriteLine("输入任意字符聊天,输入quit退出");
            Thread receiveThread = new Thread(Receive);
            receiveThread.IsBackground = true;
            receiveThread.Start();
        }
        private void Receive()
        {
            byte[] s = new byte[1024];
            try
            {
                int msglen = clientSocket.Receive(s);
                Console.WriteLine(Encoding.UTF8.GetString(s, 0, msglen));
                Receive();
            }
            catch
            {
                Console.WriteLine("服务器关闭");
            }
        }
        public void send()
        {
            Thread srThread = new Thread(SendAndRead);
            srThread.Start();
        }
        private void SendAndRead()
        {
            string s = Console.ReadLine();
            while (s != "quit")
            {
                clientSocket.Send(Encoding.UTF8.GetBytes(s));
                s = Console.ReadLine();
            }
        }
    }
}

注:本示例运行时需分开放在两个项目中运行