C#网络编程(二)------多线程socket实例

    技术2022-05-13  5

    服务器端代码:

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; namespace multithreadservTest { class Threadtcpserver { /* 本程序中采用了多线程技术,可以应付多客户的需求。首先,程序的主线程也就是程序的入口即Main()函数, * 当执行到Accept方法时,线程变会阻塞;当有新连接时,就创建相应的消息服务线程。而主程序则继续进行监听, * 检查有没有新的连接进入。如果客户端有向服务器连接的请求,那么就把连接句柄传递给接收的套接字。由于线程 * 的调度和切换是非常快的,快得足以让我们分辨不出程序的运行顺序,所以从宏观上来讲,可以说程序是并行执行 * 的。但事实上,从微观的角度上说,只是cpu飞快地调度线程,让我们感觉好像可以同时接收连接和处理消息一样, * 但在一个时刻,只有一个线程是处于运行状态的。 */ /// <summary> /// 下面这段代码的业务逻辑是: /// (1)创建套接字server,并将其与本地终结点iep进行绑定。然后,在13000端口上监听是否 有新的客户端进行连接 /// (2)在无限循环中有一个阻塞的方法Accept,该方法直到有新客户端连接到服务器上时,把 客户端的套接字信息传递给client对象。否则,将阻塞 直到有客户机进行连接。 /// (3)ClientThread类负责客户端与服务器端之间的通信。先把客户端的套接字句柄传递给 /// 负责消息服务的ClientThread类。然后,把ClientThread类 的ClientService方 法委托给线程,并启动线程。 /// </summary> private Socket server; public Threadtcpserver() { //初始化IP地址 IPAddress local=IPAddress.Parse("192.168.5.187"); IPEndPoint iep = new IPEndPoint(local, 13000); server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //将套接字与本地终结点绑定 server.Bind(iep); //在本地13000端口号上进行监听 server.Listen(20); Console.WriteLine("等待客户机进行连接......"); while (true) { //得到包含客户端信息的套接字 Socket client = server.Accept(); //创建消息服务线程对象 ClientThread newclient = new ClientThread(client); //把ClientThread类的ClientService方法委托给线程 Thread newthread = new Thread(new ThreadStart(newclient.ClientService)); //启动消息服务线程 newthread.Start(); } } /// <summary> /// (1)在构造函数中得到接收到的客户套接字client,以后就通过service句柄处理消息的接收 /// 和发送。 /// (2)ClientService方法是委托给线程的,此方法进行消息的处理工作。在这里实现的功能是, /// 先从客户端接收一条消息,然后把这条消息转换为大写字母,并立即发送一条应答的消息, /// 也就是所谓的echo技术,通常用来进行消息之间的传递。 /// (3)还有就是通过connections变量来记录活动的连接数。当有新增连接或断开连接的情况发 /// 生时,都会体现出connections的变化。 /// </summary> public class ClientThread { //connections变量表示连接数 public static int connections = 0; public Socket service; int i; //构造函数 public ClientThread(Socket clientsocket) { //service对象接管对消息的控制 this.service = clientsocket; } public void ClientService() { String data = null; byte[] bytes = new byte[1024]; //如果Socket不是空,则连接数加1 if (service != null) { connections++; } Console.WriteLine("新客户连接建立:{0}个连接数", connections); while((i=service.Receive(bytes))!=0) { data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); Console.WriteLine("收到的数据:{0}", data); //处理客户端发来的消息,这是转化为大写字母 data = data.ToUpper(); byte[] msg = System.Text.Encoding.ASCII.GetBytes(data); //发送一条应答消息 service.Send(msg); Console.WriteLine("发送的数据:{0}", data); } //关闭套接字 service.Close(); connections--; Console.WriteLine("客户关闭连接:{0}个连接数", connections); } /// <summary> /// Main函数十分简单,生成和一个Threadtcpserver实例,然后构造函数就会一步一步地 /// 展开,开始执行具体的业务逻辑。 /// </summary> /// <param name="args"></param> static void Main(string[] args) { Threadtcpserver instance = new Threadtcpserver(); } } } }

    客户端代码:

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; namespace multithreadclientTest { class Program { /// <summary> /// 本程序代码的主要功能: /// (1)创建套接字,并通过connect方法连接到本地终结点。当连接建立以后,便可以与服务器进 /// 行通讯了。 /// (2)在客户端上等待用户输入一条消息,该消息会发送到服务器创建的消息服务线程上 /// 的ClientService 方法上进行处理。在将该消息转化为大写字母后,发还给客户端。 /// 这是一个echo技术。如果在控制台上输入exit 接断开与服务器之间的连接。 /// </summary> /// <param name="args"></param> static void Main(string[] args) { Socket client; byte[] buf = new byte[1024]; string input; IPAddress local = IPAddress.Parse("192.168.5.187"); IPEndPoint iep = new IPEndPoint(local, 13000); try { client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); client.Connect(iep); } catch (SocketException) { Console.WriteLine("无法连接到服务器!"); return; } finally { } while (true) { //在控制台上输入一条消息 input = Console.ReadLine(); //输入exit,可以断开与服务器的连接 if (input == "exit") { break; } client.Send(Encoding.ASCII.GetBytes(input)); //得到实际收到的字节总数 int rec = client.Receive(buf); Console.WriteLine(Encoding.ASCII.GetString(buf, 0, rec)); } Console.WriteLine("断开与服务器的连接......"); client.Close(); } } }

     

    程序执行部分截图:

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     


    最新回复(0)