【Socket网络编程】进阶版:运用多线程

引言:

在计算机编程中,一个基本的概念就是同时对多个任务加以控制。许多程序设计问题都要求程序能够停下手头的工作,改为处理其他一些问题,再返回主进程。可以通过多种途径达到这个目的。而Unity网络的异步同步又离不开线程的运用。

目录

❤线程的定义 :

度娘定义的

 我定义的

❤交互测试

❤Socket实战运用:

服务端

 1.封装交互服务器socket。

 2.运用线程实现广播消息。

客户端 

怪怪的! 

❤源代码分享(很烂,不嫌弃的看看)


❤线程的定义 :

度娘定义的

1.每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。进程也可能是整个程序或者是部分程序的动态执行。线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行。也可以把它理解为代码运行的上下文。所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务。通常由操作系统负责多个线程的调度和执行。正在上传…重新上传取消多线程

2.线程是程序中一个单一的顺序控制流程。在单个程序中同时运行多个线程完成不同的工作,称为多线程。

3.线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈程序计数器为其执行上下文.多线程主要是为了节约CPU时间,发挥利用,根据具体情况而定。线程的运行中需要使用计算机的内存资源和CPU

 我定义的

其实线程就是一个有自己想法的类,程序执行到它后,不必“等它执行完才能执行下一行语句”,可以直接处理下一行语句。特殊情况:当子线程所执行语句与下一行语句均为循环语句,则出现交替执行情况,简称“双赢”,只能说线程是个“好人”。 

❤交互测试

❤Socket实战运用:

PS:完成简单的服务端和客户端的框架,便可以来升级“装备”了! 

在此之前,我们先回顾一下,Socket的方法中,bind()、accept()、receive()等均为阻塞方法 ,即在它们没执行或没执行成功之前则不会接着往下一条语句执行(是不是很自私!doge)。

服务端

 1.封装交互服务器socket。

我们先完善服务端的接收、发送消息的封装,为其制作一个专门的类:vipServer

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

namespace ServerPRO
{
    class vipServer
    {
        byte[] vs = new byte[4096];

        public Socket socket;
        public vipServer(Socket newSocket)
        {
            this.socket = newSocket;
            

        }
       
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="massage"></param>
        public void sendMassage(string massage)
        {           
                byte[] size = UTF8Encoding.UTF8.GetBytes(massage);
                socket.Send(size);
        }
        /// <summary>
        /// 接收消息
        /// </summary>
        public string receiveMassage()
        {

            while (true)
            {
                int size2 = socket.Receive(vs);
                string massage = Encoding.UTF8.GetString(vs, 0, size2);
                Console.WriteLine("有客户端:" + massage);
                return massage;
            }
        }
        
    }
}

 2.运用线程实现广播消息。

为了防止在while循环中的accept()方法阻塞广播消息的进行,我们则为广播消息方法进行封装,然后将其作为入口函数委托进thread,接着我们就可以start线程,畅通无阻地实现将消息广播给所有客户端。

PS:Threadstart的入口函数只能是void类型的

            
//用一个队列存储vipServer对象池

          List<vipServer> listvipServer=new List<vipServer>();

//运用子线程形成专属交互socket

            Socket newSocket = null;
            Thread thread = new Thread(new ThreadStart(broadcast));
            thread.Start();
            while (true)
            {
                newSocket = Server.Accept();


                if (newSocket != null)
                {
                    Console.WriteLine("{0}用户连接", newSocket);
                    vipServer withServer = new vipServer(newSocket);
                    listvipSocket.Add(withServer);
                    newSocket = null;

                }
                
                

            }
        //广播消息      
        void broadcast()
        {
                
                string massage = null;
                while (true)
                {
                    if (massage == null)
                    {
                        for (int i = 0; i < listvipSocket.Count; i++)
                        {
                            if (listvipSocket[i].socket != null)
                                massage = listvipSocket[i].receiveMassage();
                        }
                    }
                    if (massage != null)
                    {
                        for (int i = 0; i < listvipSocket.Count; i++)
                        {
                            listvipSocket[i].sendMassage(massage);
                            massage = null;

                        }
                    }
                }

            }

        }

客户端 

怪怪的! 

客户端的完善实际上和服务端差不多,而我也只是将客户端的接受消息可以不影响发消息,这里我没对发消息进行线程化,执行起来怪怪的!你们自己试试吧

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

namespace Client
{
    class Program
    {
        static void Main()
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            clientSocket.Connect(IPAddress.Parse("127.0.0.1"), 6060);
            Console.WriteLine("连接服务器成功...");

            byte[] sizeClient = new byte[4096];

            //接收消息的子线程
            Thread thread = new Thread(new ThreadStart(receiveMassage));
            thread.Start();
            

            string a = Console.ReadLine();
                //发送一次消息实验
            sendMassage(clientSocket, a);

            void receiveMassage()
            {
                while (true)
                {
                    int count = clientSocket.Receive(sizeClient);
                    string massage = Encoding.UTF8.GetString(sizeClient, 0, count);
                    Console.WriteLine("消息:" + massage);
                }
                
            }

        }

        /// <summary>
        /// 客户端的发送方法
        /// </summary>
        /// <param name="client"></param>
        /// <param name="abc"></param>
        public static void sendMassage(Socket client,string abc)
        {

            byte[] massageByte = Encoding.UTF8.GetBytes(abc);
            client.Send(massageByte);
        }
    }
}

❤源代码分享(很烂,不嫌弃的看看)

 Github:https://github.com/PangZaiPeiZhu/ServerPRO.git

猜你喜欢

转载自blog.csdn.net/m0_64810555/article/details/126064910