• C#网络编程多线程socket实例好啊~~


    服务器端代码:

    [c-sharp] 
    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]
    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.     }  

    程序执行部分截图:

    客户端1

    客户端2

    服务器端

     

     

  • 相关阅读:
    在 Borland C++ 及 Visual C++ 环境中使用 STLport (作者:孟岩)
    设置JavaFX-CSS改变TreeView节点图标
    Using MS DataGrid control with ADO
    两个加载fxml文件的方法
    JavaFX中ObservableValue类型
    在 Eclipse 下利用 gradle 构建系统
    JavaFX初探
    深度剖析如何保证缓存与数据库的一致性
    ACID的实现原理
    一颗高度为3的B+树能存多少行数据?
  • 原文地址:https://www.cnblogs.com/lkskevin/p/2524565.html
Copyright © 2020-2023  润新知