C# 控制台聊天(socket编程初识)

控制台客户端

代码

命名空间:

using System;
using System.Net;//
using System.Net.Sockets;//包括
using System.Text;//
using System.Threading;//线程调用

字段:

private static int bufferSize = 1024;
//要连接的IP
private static string host = "127.0.0.1";
//这是要连接的端口号
private static int port = 8080;
private static IPAddress iPAddress = IPAddress.Parse(host);
//保存端口号和类
private static IPEndPoint ToipEnd = new IPEndPoint(iPAddress, port);
//保存本机的端口号和类
//这里是和本机交互,所以IP相同,端口号我直接给绑了45199
private static IPEndPoint localipEnd = new IPEndPoint(iPAddress, 45199);
//俩天序号
private static int Count = 0;
//本地的Socket
static Socket socketOfClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

注:上面代码里我直接给客户端绑定了端口号,实际上不用绑定,连接到服务器会自动分配端口号。
main函数如下:

 static void Main(string[] args)
        {
            //绑定45199,不用绑定
            //socketOfClient.Bind(localipEnd);
            try
            {
                //连接8080
                socketOfClient.Connect(ToipEnd);
                Console.WriteLine("连成功" + socketOfClient.RemoteEndPoint);
                Console.WriteLine("开始聊天");
            }
            catch (Exception e)
            {
                throw new Exception(e.ToString());
            }
            Thread threadOfSend = new Thread(SendMessage);
            //记得在Start方法里面传送对象,这些对象都会被装箱。
            threadOfSend.Start(socketOfClient);
            Thread thread1OfRecive = new Thread(ReciveMsg);
            thread1OfRecive.Start(socketOfClient);
        }

发送方法:

//发送信息方法
        private static void SendMessage(object o)
        {
            Socket socketOfPeer = o as Socket;
            while (true)
            {
                try
                {
                    byte[] buffer = new byte[bufferSize];
                    string msg = Console.ReadLine();
                    Console.WriteLine($"[{socketOfClient.LocalEndPoint}] 我:\n{msg}");
                    if (msg != string.Empty)
                    {
                        buffer = Encoding.UTF8.GetBytes(msg);
                        //这里客户端socket使用Send向Remote发送信息
                        socketOfPeer.Send(buffer);
                    }
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
        }

接受方法:

private static void ReciveMsg(object o)
        {
            Socket socketOfPeer = o as Socket;
            while (true)
            {
                Console.WriteLine("接受信息。。");
                byte[] buffer = new byte[bufferSize];
                try
                {
                    int length = socketOfPeer.Receive(buffer);
                    byte[] realBuffer = new byte[length];
                    Array.Copy(buffer, 0, realBuffer, 0, length);
                    string msg = Encoding.UTF8.GetString(realBuffer);
                    Console.WriteLine($"[{Count++}]  [{socketOfPeer.RemoteEndPoint}]说:");
                    Console.WriteLine($"{msg}");
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
        }

流程

1.主线程,main函数中,直接connect进行连接(服务器必须提前启动)。连接诶成功后,将socket交给2个线程,循环接受和发送信息即可。

服务器客户端

代码

字段:

private static string serverIP = "127.0.0.1";
        private static int host = 8080;
        private static int endHost = 45199;
        private static IPAddress iPAddress = IPAddress.Parse(serverIP);
        private static IPEndPoint toIpEnd = new IPEndPoint(iPAddress, endHost);
        private static IPEndPoint localIpEnd = new IPEndPoint(iPAddress, host);
        private static Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private static int count = 0;
        private static int bufferMax = 1024;

main函数:

 static void Main()
        {
        	//服务器一定要绑定端口号和ip
            server.Bind(localIpEnd);
            try
            {
                Console.WriteLine($"本机:{server.LocalEndPoint}");
                Console.WriteLine($"正在连接");
                //Connect是直接连接指定的ip和端口,这里要使用Listen
                //server.Connect(toIpEnd);
                //listen函数进行监听,最大连接数是10个
                server.Listen(10);
            }
            catch (Exception e)
            {
                Console.WriteLine($"{e}");
            }
            Thread threadSend = new Thread(Run);
            threadSend.Start(server);
        }

Run方法:

private static void Run(object o)
    {
        Socket socket = o as Socket;

        try
        {
            //这是保存的新的Socket
            Socket connSocket = socket.Accept();
            //此处使用一下语句会报错,因为旧的socket没有保存连接的信息
        	//Console.WriteLine($"{socket.RemoteEndPoint}");
        	//以下是对的
			//Console.WriteLine($"{connSocket .RemoteEndPoint}");
            //客户和服务器连接成功。
            Console.WriteLine("{0}成功连接到本机。", connSocket.RemoteEndPoint);
            //接下来的事情交给会话线程
            Thread recTh = new Thread(ReciveMsg);
            recTh.Start(connSocket);
            Thread sendTh = new Thread(SendMessage);
            sendTh.Start(connSocket);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            throw;
        }
    }

**注:
以上方法中,第一个socket 是本服务端的socket对象。
第二个conSocket是在socket对象接受到连接时new的新对象,这个新对象才包含连接对象的信息,而socket是没有的。
可以打印socket的LocalEndPoint和RemoteEndPoint,查看各个socket的信息。
服务器中会话线程的函数是和客户端一样的。
**

流程

1.mian函数中,主线程绑定服务器IP(bind),开启侦听(listen),开启一个新线程,将socket对象交给新线程,运行run函数 处理连接信息。

2.在Run方法中,服务器socket进行监听(listen函数),使用Accept接收连接。如果没有连接,Accept会阻塞(因为只有接收到连接,后面的代码才能进行与之通信),直到Accept接收到连接并保存。这时服务器和客户端的socket已经建立起连接了。这时开始2个新线程,循环处理发送和接受信息。

socket运行流程图示

在这里插入图片描述

参考文章

http://www.west999.com/cms/wiki/code/2018-07-20/36646.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值