欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#使用Socket实现本地多人聊天室

程序员文章站 2022-06-04 08:08:48
本文实例为大家分享了c#使用socket实现本地多人聊天室的具体代码,供大家参考,具体内容如下【脚本一:server端】使用本机地址:127.0.0.1完整代码using system;using s...

本文实例为大家分享了c#使用socket实现本地多人聊天室的具体代码,供大家参考,具体内容如下

【脚本一:server端】

使用本机地址:127.0.0.1

完整代码

using system;
using system.collections.generic;
using system.net;
using system.net.sockets;
using system.text;
using system.threading;
 
namespace consoleapp1
{
    public class server
    {
        socket mysocket = null;
        dictionary<ipaddress, socket> clidic = new dictionary<ipaddress, socket>();
 
        public void connect(int port)
        {
            string ip = "127.0.0.1";
            //ipaddress ipaddress = ipaddress.parse("127.0.0.1");
            ipaddress address = ipaddress.any;
            //创建ip终结点,把ip地址与端口绑定到网络终结点上
            ipendpoint endpoint = new ipendpoint(address, port);
            //创建客户端套接字
            mysocket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);
            ///监听套接字终结点
            mysocket.bind(endpoint);
            //服务端可接收客户端连接数量为无限个
            mysocket.listen(0);
            //开启线程监听客户端
            thread mythread = new thread(listen_con);
            mythread.start();
            console.writeline("开始监听...");
        }
 
        /// <summary>
        /// 接收连接的客户端并存储客户端的信息
        /// </summary>
        /// <param name="obj"></param>
        public void listen_con(object obj)
        {
            socket clisocket = null;
            //持续监听客户端的请求
            while (true)
            {
                try
                {
                    clisocket = mysocket.accept();
                }
                catch (exception e)
                {
                    console.writeline(e.message);
                }
                string cliendpoint = clisocket.remoteendpoint.tostring();
                ipaddress cliaddress = (clisocket.remoteendpoint as ipendpoint).address;
                int cliport = (clisocket.remoteendpoint as ipendpoint).port;
                clidic.add(cliaddress, clisocket);
                string msgstr = "[客户端结点:" + cliendpoint + "\n+客户端ip:" + cliaddress.tostring() + "\n客户端端口:" +
                    cliport.tostring() + "\n已连接]";
                byte[] msgbytes = encoding.utf8.getbytes(msgstr);
                clisocket.send(msgbytes);
 
                thread rec_cli = new thread(receive_con);
                rec_cli.start(clisocket);
                thread sed_cli = new thread(sendtocli);
                sed_cli.start(clisocket);
            }
        }
 
        /// <summary>
        /// 接收已连接的客户端发送的消息
        /// </summary>
        /// <param name="socket"></param>
        public void receive_con(object socket)
        {
            socket client = socket as socket;
            while (true)
            {
                //创建大小为1024*1024的内存缓冲区(1m)
                byte[] recbytes = new byte[1024 * 1024];
                //尝试把接收的字节存储到缓冲区
                try
                {
                    int length = client.receive(recbytes);
                    //把机器接收的字节数组转换为string
                    string recmsg = encoding.utf8.getstring(recbytes, 0, length);
                    //将服务器接收到的信息转发到所有已连接的客户端
                    if (clidic.count > 0)
                    {
                        foreach (var soc in clidic)
                        {
                            soc.value.send(encoding.utf8.getbytes("[" + soc.value.remoteendpoint + "]:" + recmsg));
                        }
                    }
                    console.writeline("[" + client.remoteendpoint + "]:" + recmsg);
                }
                catch (exception)
                {
                    clidic.remove((client.remoteendpoint as ipendpoint).address);
                    //客户端断开的异常
                    console.writeline("[客户端" + (client.remoteendpoint as ipendpoint).address + "已断开]");
                    console.writeline("[客户端终结点:" + client.remoteendpoint+"]");
                    //断开套接字
                    client.close();
                    break;
                }
            }
        }
 
        public void sendtocli(object obj)
        {
            socket curclisoc = obj as socket;
            while (true)
            {
                byte[] bytetoall = new byte[1024 * 1024];
                try
                {
                    string msgtoall = console.readline();
                    bytetoall = encoding.utf8.getbytes("[服务端]:"+msgtoall);
                    curclisoc.send(bytetoall);
                }
                catch(exception)
                {
                    console.writeline("error:" + curclisoc.remoteendpoint + "已与服务端断开!");
                    curclisoc.close();
                    if(clidic.containskey((curclisoc.remoteendpoint as ipendpoint).address))
                    {
                        clidic.remove((curclisoc.remoteendpoint as ipendpoint).address);
                    }
                }
            }
        }
    }
 
    public class servermain
    {
        static void main(string[] args)
        {
            server s1 = new server();
            s1.connect(8800);
        }
    }
}

server端运行结果:

C#使用Socket实现本地多人聊天室

【脚本二:client端】

完整代码

using system;
using system.net;
using system.net.sockets;
using system.text;
using system.threading;
 
namespace consoleapp1
{
    public class client
    {
        string serip = "127.0.0.1";
        socket myclient = null;
        thread connectthread = null;
        ipaddress seradd;
        ipendpoint serep;
        public void connect_to_ser(int port)
        {
            myclient = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);
            seradd = ipaddress.parse(serip);
            serep = new ipendpoint(seradd, port);
            while (true)
            {
                try
                {
                    myclient.connect(serep);
                    break;
                }
                catch
                {
                    console.writeline("无法连接到服务端,请重试...");
                }
            }
            connectthread = new thread(receive_ser);
            connectthread.start();
        }
 
        public void receive_ser()
        {
            while (true)
            {
                byte[] serbytes = new byte[1024 * 1024];
                try
                {
                    int length = myclient.receive(serbytes);
                    string msg = encoding.utf8.getstring(serbytes, 0, length);
                    console.writeline(msg);
                }
                catch (exception)
                {
                    console.writeline("已与服务端断开连接...");
                    break;
                }
            }
        }
 
        public void sendtoser()
        {
            while (true)
            {
                try
                {
                    string sendmsg = console.readline();
                    myclient.send(encoding.utf8.getbytes(sendmsg));
                }
                catch (exception)
                {
                    console.writeline("[sendtoser]已断开连接");
                    break;
                }
            }
        }
    }
 
    public class clienmain
    {
        static void main(string[] args)
        {
            client c1 = new client();
            c1.connect_to_ser(8800);
            c1.sendtoser();
        }
    }
}

客户端运行效果:

①客户端先于服务端运行

C#使用Socket实现本地多人聊天室

②客户端迟于服务端运行

C#使用Socket实现本地多人聊天室

暂时总效果:

C#使用Socket实现本地多人聊天室

功能完善:

①客户端连上服务端后若服务端断开再打开,客户端无法重连

②心跳包重连

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。