C#网络编程之多线程socket实例

来源:互联网 发布:分期乐网络繁忙 编辑:程序博客网 时间:2024/04/29 08:21

服务器端:

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 0
原创粉丝点击