分享

C#网络编程(二)

 根的情义 2017-05-13

分类: C#

服务器端代码:

[c-sharp] view plaincopy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Net;  
  6. using System.Net.Sockets;  
  7. using System.Threading;  
  8.   
  9. namespace multithreadservTest  
  10. {  
  11.     class Threadtcpserver  
  12.     {  
  13.   
  14.         /* 本程序中采用了多线程技术,可以应付多客户的需求。首先,程序的主线程也就是程序的入口即Main()函数, 
  15.          * 当执行到Accept方法时,线程变会阻塞;当有新连接时,就创建相应的消息服务线程。而主程序则继续进行监听, 
  16.          * 检查有没有新的连接进入。如果客户端有向服务器连接的请求,那么就把连接句柄传递给接收的套接字。由于线程 
  17.          * 的调度和切换是非常快的,快得足以让我们分辨不出程序的运行顺序,所以从宏观上来讲,可以说程序是并行执行 
  18.          * 的。但事实上,从微观的角度上说,只是cpu飞快地调度线程,让我们感觉好像可以同时接收连接和处理消息一样, 
  19.          * 但在一个时刻,只有一个线程是处于运行状态的。 
  20.          */  
  21.   
  22.   
  23.         /// <summary>  
  24.         /// 下面这段代码的业务逻辑是:  
  25.         /// (1)创建套接字server,并将其与本地终结点iep进行绑定。然后,在13000端口上监听是否  
  26.                   有新的客户端进行连接  
  27.         /// (2)在无限循环中有一个阻塞的方法Accept,该方法直到有新客户端连接到服务器上时,把  
  28.                   客户端的套接字信息传递给client对象。否则,将阻塞 直到有客户机进行连接。  
  29.         /// (3)ClientThread类负责客户端与服务器端之间的通信。先把客户端的套接字句柄传递给  
  30.         ///       负责消息服务的ClientThread类。然后,把ClientThread类 的ClientService方  
  31.                   法委托给线程,并启动线程。   
  32.         /// </summary>  
  33.         private Socket server;  
  34.         public Threadtcpserver()  
  35.         {  
  36.             //初始化IP地址  
  37.             IPAddress local=IPAddress.Parse('192.168.5.187');  
  38.             IPEndPoint iep = new IPEndPoint(local, 13000);  
  39.             server = new Socket(AddressFamily.InterNetwork, SocketType.Stream,  
  40.             ProtocolType.Tcp);  
  41.             //将套接字与本地终结点绑定  
  42.             server.Bind(iep);  
  43.             //在本地13000端口号上进行监听  
  44.             server.Listen(20);  
  45.             Console.WriteLine('等待客户机进行连接......');  
  46.             while (true)  
  47.             {  
  48.                 //得到包含客户端信息的套接字  
  49.                 Socket client = server.Accept();  
  50.                 //创建消息服务线程对象  
  51.                 ClientThread newclient = new ClientThread(client);  
  52.                 //把ClientThread类的ClientService方法委托给线程  
  53.                 Thread newthread = new Thread(new ThreadStart(newclient.ClientService));  
  54.                 //启动消息服务线程  
  55.                 newthread.Start();  
  56.                        
  57.             }  
  58.   
  59.   
  60.         }  
  61.   
  62.   
  63.         /// <summary>  
  64.         /// (1)在构造函数中得到接收到的客户套接字client,以后就通过service句柄处理消息的接收  
  65.          ///      和发送。  
  66.         /// (2)ClientService方法是委托给线程的,此方法进行消息的处理工作。在这里实现的功能是,  
  67.         ///       先从客户端接收一条消息,然后把这条消息转换为大写字母,并立即发送一条应答的消息,  
  68.         ///      也就是所谓的echo技术,通常用来进行消息之间的传递。  
  69.         /// (3)还有就是通过connections变量来记录活动的连接数。当有新增连接或断开连接的情况发   
  70.         ///       生时,都会体现出connections的变化。  
  71.        /// </summary>  
  72.         public class ClientThread  
  73.         {  
  74.             //connections变量表示连接数  
  75.             public static int connections = 0;  
  76.             public Socket service;  
  77.             int i;  
  78.             //构造函数  
  79.             public ClientThread(Socket clientsocket)  
  80.             {  
  81.                 //service对象接管对消息的控制  
  82.                 this.service = clientsocket;  
  83.             }  
  84.             public void ClientService()  
  85.             {  
  86.                 String data = null;  
  87.                 byte[] bytes = new byte[1024];  
  88.                 //如果Socket不是空,则连接数加1  
  89.                 if (service != null)  
  90.                 {  
  91.                     connections ;  
  92.                 }  
  93.                 Console.WriteLine('新客户连接建立:{0}个连接数', connections);  
  94.                 while((i=service.Receive(bytes))!=0)  
  95.                 {  
  96.                     data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);  
  97.                     Console.WriteLine('收到的数据:{0}', data);  
  98.                     //处理客户端发来的消息,这是转化为大写字母  
  99.                     data = data.ToUpper();  
  100.                     byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);  
  101.                     //发送一条应答消息  
  102.                     service.Send(msg);  
  103.                     Console.WriteLine('发送的数据:{0}', data);  
  104.                 }  
  105.                 //关闭套接字  
  106.                 service.Close();  
  107.                 connections--;  
  108.                 Console.WriteLine('客户关闭连接:{0}个连接数', connections);  
  109.             }  
  110.   
  111.   
  112.             /// <summary>  
  113.             /// Main函数十分简单,生成和一个Threadtcpserver实例,然后构造函数就会一步一步地  
  114.               /// 展开,开始执行具体的业务逻辑。  
  115.             /// </summary>  
  116.             /// <param name='args'></param>  
  117.             static void Main(string[] args)  
  118.             {  
  119.                 Threadtcpserver instance = new Threadtcpserver();  
  120.             }  
  121.   
  122.   
  123.         }  
  124.               
  125.   
  126.   
  127.   
  128.   
  129.   
  130.   
  131.   
  132.   
  133.           
  134.     }  
  135. }  

客户端代码:

[c-sharp] view plaincopy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Net;  
  6. using System.Net.Sockets;  
  7.   
  8.   
  9. namespace multithreadclientTest  
  10. {  
  11.     class Program  
  12.     {  
  13.         /// <summary>  
  14.         /// 本程序代码的主要功能:  
  15.         /// (1)创建套接字,并通过connect方法连接到本地终结点。当连接建立以后,便可以与服务器进  
  16.         ///       行通讯了。  
  17.         /// (2)在客户端上等待用户输入一条消息,该消息会发送到服务器创建的消息服务线程上  
  18.         ///       的ClientService 方法上进行处理。在将该消息转化为大写字母后,发还给客户端。  
  19.         ///       这是一个echo技术。如果在控制台上输入exit 接断开与服务器之间的连接。  
  20.         /// </summary>  
  21.         /// <param name='args'></param>  
  22.         static void Main(string[] args)  
  23.         {  
  24.             Socket client;  
  25.             byte[] buf = new byte[1024];  
  26.             string input;  
  27.             IPAddress local = IPAddress.Parse('192.168.5.187');  
  28.             IPEndPoint iep = new IPEndPoint(local, 13000);  
  29.   
  30.             try  
  31.             {  
  32.                 client = new Socket(AddressFamily.InterNetwork, SocketType.Stream,  
  33.                 ProtocolType.Tcp);  
  34.                 client.Connect(iep);  
  35.             }  
  36.             catch (SocketException)  
  37.             {  
  38.                 Console.WriteLine('无法连接到服务器!');  
  39.                 return;  
  40.             }  
  41.             finally  
  42.             {  
  43.   
  44.             }  
  45.             while (true)  
  46.             {  
  47.                 //在控制台上输入一条消息  
  48.                 input = Console.ReadLine();  
  49.                 //输入exit,可以断开与服务器的连接  
  50.                 if (input == 'exit')  
  51.                 {  
  52.                     break;  
  53.                 }  
  54.                 client.Send(Encoding.ASCII.GetBytes(input));  
  55.                 //得到实际收到的字节总数  
  56.                 int rec = client.Receive(buf);  
  57.                 Console.WriteLine(Encoding.ASCII.GetString(buf, 0, rec));  
  58.   
  59.             }  
  60.             Console.WriteLine('断开与服务器的连接......');  
  61.             client.Close();  
  62.   
  63.   
  64.         }  
  65.     }  
  66. }  

 

程序执行部分截图:

 

客户端1

 

客户端2

 

 

服务器端

 

 

 

  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约