C#网络编程TCP通信实例程序简单设计

来源:互联网 发布:大数据讲座主持词 编辑:程序博客网 时间:2024/04/27 10:19

转载连接: http://blog.csdn.net/CoderJYF/article/details/70255309#reply


目录(?)[+]

C#网络编程TCP通信实例程序简单设计

采用自带 TcpClient和TcpListener设计一个Tcp通信的例子

只实现了TCP通信

通信程序截图:

压力测试服务端截图:

俩个客户端链接服务端测试截图:

服务端:

客户端

运行动态图

C#程序设计代码

BenXHSocket.dll主要代码设计

SocketObject类

[csharp] view plain copy
  1. /***************************************************** 
  2.  * ProjectName:  BenXHSocket 
  3.  * Description: 
  4.  * ClassName:    SocketObject 
  5.  * CLRVersion:   4.0.30319.18408 
  6.  * Author:       JiYF 
  7.  * NameSpace:    BenXHSocket 
  8.  * MachineName:  JIYONGFEI 
  9.  * CreateTime:   2017/3/31 12:13:06 
  10.  * UpdatedTime:  2017/3/31 12:13:06 
  11. *****************************************************/  
  12. using System;  
  13. using System.Collections.Generic;  
  14. using System.Linq;  
  15. using System.Text;  
  16. using System.Net;  
  17.   
  18. namespace BenXHSocket  
  19. {  
  20.     /// <summary>  
  21.     /// Socket基础类  
  22.     /// </summary>  
  23.     public abstract class SocketObject  
  24.     {  
  25.         /// <summary>  
  26.         /// 初始化Socket方法  
  27.         /// </summary>  
  28.         /// <param name="ipAddress"></param>  
  29.         /// <param name="port"></param>  
  30.         public abstract void InitSocket(IPAddress ipAddress,int port);  
  31.         public abstract void InitSocket(string ipAddress,int port);  
  32.   
  33.         /// <summary>  
  34.         /// Socket启动方法  
  35.         /// </summary>  
  36.         public abstract void Start();  
  37.   
  38.         /// <summary>  
  39.         /// Sockdet停止方法  
  40.         /// </summary>  
  41.         public abstract void Stop();  
  42.   
  43.     }  
  44. }  

sockets类

[csharp] view plain copy
  1. /***************************************************** 
  2.  * ProjectName:  BenXHSocket 
  3.  * Description: 
  4.  * ClassName:    Sockets 
  5.  * CLRVersion:   4.0.30319.18408 
  6.  * Author:       JiYF 
  7.  * NameSpace:    BenXHSocket 
  8.  * MachineName:  JIYONGFEI 
  9.  * CreateTime:   2017/3/31 12:16:10 
  10.  * UpdatedTime:  2017/3/31 12:16:10 
  11. *****************************************************/  
  12. using System;  
  13. using System.Collections.Generic;  
  14. using System.Linq;  
  15. using System.Text;  
  16. using System.Net;  
  17. using System.Net.Sockets;  
  18.   
  19. namespace BenXHSocket  
  20. {  
  21.     public class Sockets  
  22.     {  
  23.         /// <summary>  
  24.         /// 接收缓冲区大小8k  
  25.         /// </summary>  
  26.         public byte[] RecBuffer = new byte[8 * 1024];   
  27.    
  28.         /// <summary>  
  29.         /// 发送缓冲区大小8k  
  30.         /// </summary>  
  31.         public byte[] SendBuffer = new byte[8 * 1024];  
  32.   
  33.         /// <summary>  
  34.         /// 异步接收后包的大小  
  35.         /// </summary>  
  36.         public int Offset { get;set;}  
  37.   
  38.         /// <summary>  
  39.         /// 当前IP地址,端口号  
  40.         /// </summary>  
  41.         public IPEndPoint Ip { getset; }  
  42.         /// <summary>  
  43.         /// 客户端主通信程序  
  44.         /// </summary>  
  45.         public TcpClient Client { getset; }  
  46.         /// <summary>  
  47.         /// 承载客户端Socket的网络流  
  48.         /// </summary>  
  49.         public NetworkStream nStream { getset; }  
  50.   
  51.         /// <summary>  
  52.         /// 发生异常时不为null.  
  53.         /// </summary>  
  54.         public Exception ex { getset; }  
  55.   
  56.         /// <summary>  
  57.         /// 新客户端标识.如果推送器发现此标识为true,那么认为是客户端上线  
  58.         /// 仅服务端有效  
  59.         /// </summary>  
  60.         public bool NewClientFlag { getset; }  
  61.   
  62.         /// <summary>  
  63.         /// 客户端退出标识.如果服务端发现此标识为true,那么认为客户端下线  
  64.         /// 客户端接收此标识时,认为客户端异常.  
  65.         /// </summary>  
  66.         public bool ClientDispose { getset; }  
  67.   
  68.         /// <summary>  
  69.         /// 空参构造  
  70.         /// </summary>  
  71.         public Sockets() { }  
  72.   
  73.         /// <summary>  
  74.         /// 构造函数  
  75.         /// </summary>  
  76.         /// <param name="ip">ip节点</param>  
  77.         /// <param name="client">TCPClient客户端</param>  
  78.         /// <param name="ns">NetworkStream </param>  
  79.         public Sockets(IPEndPoint ip,TcpClient client,NetworkStream ns)  
  80.         {  
  81.             this.Ip = ip;  
  82.             this.Client = client;  
  83.             this.nStream = ns;  
  84.         }  
  85.     }  
  86. }  
SocketsHandler类
[csharp] view plain copy
  1. /***************************************************** 
  2.  * ProjectName:  BenXHSocket 
  3.  * Description: 
  4.  * ClassName:    SocketsHandler 
  5.  * CLRVersion:   4.0.30319.18408 
  6.  * Author:       JiYF 
  7.  * NameSpace:    BenXHSocket 
  8.  * MachineName:  JIYONGFEI 
  9.  * CreateTime:   2017/3/31 13:42:48 
  10.  * UpdatedTime:  2017/3/31 13:42:48 
  11. *****************************************************/  
  12. using System;  
  13. using System.Collections.Generic;  
  14. using System.Linq;  
  15. using System.Text;  
  16.   
  17. namespace BenXHSocket  
  18. {  
  19.     /// <summary>  
  20.     /// 推送器  
  21.     /// </summary>  
  22.     /// <param name="sockets"></param>  
  23.     public delegate void PushSockets(Sockets sockets);  
  24.       
  25. }  

BXHTcpServer类 tcp服务端监听类

[csharp] view plain copy
  1. /***************************************************** 
  2.  * ProjectName:  BenXHSocket 
  3.  * Description: 
  4.  * ClassName:    TcpServer 
  5.  * CLRVersion:   4.0.30319.18408 
  6.  * Author:       JiYF 
  7.  * NameSpace:    BenXHSocket 
  8.  * MachineName:  JIYONGFEI 
  9.  * CreateTime:   2017/3/31 12:24:08 
  10.  * UpdatedTime:  2017/3/31 12:24:08 
  11. *****************************************************/  
  12. using System;  
  13. using System.Collections.Generic;  
  14. using System.Linq;  
  15. using System.Text;  
  16. using System.Threading;  
  17. using System.Net;  
  18. using System.Net.Sockets;  
  19.   
  20. namespace BenXHSocket  
  21. {  
  22.     /// <summary>  
  23.     /// TCPServer类 服务端程序  
  24.     /// </summary>  
  25.     public class BXHTcpServer:SocketObject  
  26.     {  
  27.         private bool IsStop = false;  
  28.         object obj = new object();  
  29.         public static PushSockets pushSockets;  
  30.   
  31.         /// <summary>  
  32.         /// 信号量  
  33.         /// </summary>  
  34.         private Semaphore semap = new Semaphore(5,5000);  
  35.   
  36.         /// <summary>  
  37.         /// 客户端列表集合  
  38.         /// </summary>  
  39.         public List<Sockets> ClientList = new List<Sockets>();  
  40.   
  41.         /// <summary>  
  42.         /// 服务端实例对象  
  43.         /// </summary>  
  44.         public TcpListener Listener;  
  45.   
  46.         /// <summary>  
  47.         /// 当前的ip地址  
  48.         /// </summary>  
  49.         private IPAddress IpAddress;  
  50.   
  51.         /// <summary>  
  52.         /// 初始化消息  
  53.         /// </summary>  
  54.         private string InitMsg = "JiYF笨小孩TCP服务端";  
  55.   
  56.         /// <summary>  
  57.         /// 监听的端口  
  58.         /// </summary>  
  59.         private int Port;  
  60.   
  61.         /// <summary>  
  62.         /// 当前ip和端口节点对象  
  63.         /// </summary>  
  64.         private IPEndPoint Ip;  
  65.   
  66.   
  67.         /// <summary>  
  68.         /// 初始化服务器对象  
  69.         /// </summary>  
  70.         /// <param name="ipAddress">IP地址</param>  
  71.         /// <param name="port">端口号</param>  
  72.         public override void InitSocket(IPAddress ipAddress, int port)  
  73.         {  
  74.             this.IpAddress = ipAddress;  
  75.             this.Port = port;  
  76.             this.Listener = new TcpListener(IpAddress,Port);  
  77.         }  
  78.   
  79.         /// <summary>  
  80.         /// 初始化服务器对象  
  81.         /// </summary>  
  82.         /// <param name="ipAddress"></param>  
  83.         /// <param name="port"></param>  
  84.         public override void InitSocket(string ipAddress, int port)  
  85.         {  
  86.             this.IpAddress = IPAddress.Parse(ipAddress);  
  87.             this.Port = port;  
  88.             this.Ip = new IPEndPoint(IpAddress,Port);  
  89.             this.Listener = new TcpListener(IpAddress,Port);  
  90.         }  
  91.   
  92.         /// <summary>  
  93.         /// 服务端启动监听,处理链接  
  94.         /// </summary>  
  95.         public override void Start()  
  96.         {  
  97.             try  
  98.             {   
  99.                 Listener.Start();  
  100.                 Thread Accth = new Thread(new ThreadStart(  
  101.                     delegate  
  102.                     {  
  103.                         while(true)  
  104.                         {  
  105.                             if(IsStop != false)  
  106.                             {  
  107.                                 break;  
  108.                             }  
  109.                             this.GetAcceptTcpClient();  
  110.                             Thread.Sleep(1);  
  111.                         }  
  112.                     }  
  113.                     ));  
  114.                 Accth.Start();  
  115.             }  
  116.             catch(SocketException skex)  
  117.             {  
  118.                 Sockets sks = new Sockets();  
  119.                 sks.ex = skex;  
  120.                 pushSockets.Invoke(sks);  
  121.             }  
  122.         }  
  123.   
  124.         /// <summary>  
  125.         /// 获取处理新的链接请求  
  126.         /// </summary>  
  127.         private void GetAcceptTcpClient()  
  128.         {  
  129.             try  
  130.             {   
  131.                 if(Listener.Pending())  
  132.                 {  
  133.                     semap.WaitOne();  
  134.                     //接收到挂起的客户端请求链接  
  135.                     TcpClient tcpClient = Listener.AcceptTcpClient();  
  136.   
  137.                     //维护处理客户端队列  
  138.                     Socket socket = tcpClient.Client;  
  139.                     NetworkStream stream = new NetworkStream(socket,true);  
  140.                     Sockets sks = new Sockets(tcpClient.Client.RemoteEndPoint as IPEndPoint,tcpClient,stream);  
  141.                     sks.NewClientFlag = true;  
  142.   
  143.                     //推送新的客户端连接信息  
  144.                     pushSockets.Invoke(sks);  
  145.   
  146.                     //客户端异步接收数据  
  147.                     sks.nStream.BeginRead(sks.RecBuffer,0,sks.RecBuffer.Length,new AsyncCallback(EndReader),sks);  
  148.                       
  149.                     //加入客户端队列  
  150.                     this.AddClientList(sks);  
  151.   
  152.                     //链接成功后主动向客户端发送一条消息  
  153.                     if(stream.CanWrite)  
  154.                     {  
  155.                         byte[] buffer = Encoding.UTF8.GetBytes(this.InitMsg);  
  156.                         stream.Write(buffer, 0, buffer.Length);  
  157.                     }  
  158.                     semap.Release();  
  159.                 }  
  160.             }  
  161.             catch  
  162.             {  
  163.                 return;  
  164.             }  
  165.         }  
  166.   
  167.         /// <summary>  
  168.         /// 异步接收发送的的信息  
  169.         /// </summary>  
  170.         /// <param name="ir"></param>  
  171.         private void EndReader(IAsyncResult ir)  
  172.         {  
  173.             Sockets sks = ir.AsyncState as Sockets;  
  174.             if (sks != null && Listener != null)  
  175.             {  
  176.                 try  
  177.                 {  
  178.                     if (sks.NewClientFlag || sks.Offset != 0)  
  179.                     {  
  180.                         sks.NewClientFlag = false;  
  181.                         sks.Offset = sks.nStream.EndRead(ir);  
  182.                         //推送到UI  
  183.                         pushSockets.Invoke(sks);  
  184.                         sks.nStream.BeginRead(sks.RecBuffer,0,sks.RecBuffer.Length,new AsyncCallback(EndReader),sks);  
  185.                     }  
  186.                 }  
  187.                 catch(Exception skex)  
  188.                 {  
  189.                     lock (obj)  
  190.                     {  
  191.                         ClientList.Remove(sks);  
  192.                         Sockets sk = sks;  
  193.                         //标记客户端退出程序  
  194.                         sk.ClientDispose = true;  
  195.                         sk.ex = skex;  
  196.                         //推送至UI  
  197.                         pushSockets.Invoke(sks);  
  198.                     }  
  199.                 }  
  200.             }  
  201.         }  
  202.   
  203.         /// <summary>  
  204.         /// 客户端加入队列  
  205.         /// </summary>  
  206.         /// <param name="sk"></param>  
  207.         private void AddClientList(Sockets sk)  
  208.         {  
  209.             lock (obj)  
  210.             {  
  211.                 Sockets sockets = ClientList.Find(o => { return o.Ip == sk.Ip; });  
  212.                 if (sockets == null)  
  213.                 {  
  214.                     ClientList.Add(sk);  
  215.                 }  
  216.                 else  
  217.                 {  
  218.                     ClientList.Remove(sockets);  
  219.                     ClientList.Add(sk);  
  220.                 }  
  221.             }  
  222.         }  
  223.   
  224.         /// <summary>  
  225.         /// 服务端停止监听  
  226.         /// </summary>  
  227.         public override void Stop()  
  228.         {  
  229.             if (Listener != null)  
  230.             {  
  231.                 Listener.Stop();  
  232.                 Listener = null;  
  233.                 IsStop = true;  
  234.                 pushSockets = null;  
  235.             }  
  236.         }  
  237.   
  238.         /// <summary>  
  239.         /// 向所有在线客户端发送消息  
  240.         /// </summary>  
  241.         /// <param name="SendData">消息内容</param>  
  242.         public void SendToAll(string SendData)  
  243.         {  
  244.             for (int i = 0; i < ClientList.Count; i++)  
  245.             {  
  246.                 SendToClient(ClientList[i].Ip, SendData);  
  247.             }  
  248.         }  
  249.   
  250.         /// <summary>  
  251.         /// 向单独的一个客户端发送消息  
  252.         /// </summary>  
  253.         /// <param name="ip"></param>  
  254.         /// <param name="SendData"></param>  
  255.         public void SendToClient(IPEndPoint ip,string SendData)  
  256.         {  
  257.             try  
  258.             {  
  259.                 Sockets sks = ClientList.Find(o => { return o.Ip == ip; });  
  260.                 if(sks == null || !sks.Client.Connected)  
  261.                 {  
  262.                     Sockets ks = new Sockets();  
  263.                     //标识客户端下线  
  264.                     sks.ClientDispose = true;  
  265.                     sks.ex = new Exception("客户端没有连接");  
  266.                     pushSockets.Invoke(sks);  
  267.                 }  
  268.                 if(sks.Client.Connected)  
  269.                 {  
  270.                      //获取当前流进行写入.  
  271.                         NetworkStream nStream = sks.nStream;  
  272.                         if (nStream.CanWrite)  
  273.                         {  
  274.                             byte[] buffer = Encoding.UTF8.GetBytes(SendData);  
  275.                             nStream.Write(buffer, 0, buffer.Length);  
  276.                         }  
  277.                         else  
  278.                         {  
  279.                             //避免流被关闭,重新从对象中获取流  
  280.                             nStream = sks.Client.GetStream();  
  281.                             if (nStream.CanWrite)  
  282.                             {  
  283.                                 byte[] buffer = Encoding.UTF8.GetBytes(SendData);  
  284.                                 nStream.Write(buffer, 0, buffer.Length);  
  285.                             }  
  286.                             else  
  287.                             {  
  288.                                 //如果还是无法写入,那么认为客户端中断连接.  
  289.                                 ClientList.Remove(sks);  
  290.                                 Sockets ks = new Sockets();  
  291.                                 sks.ClientDispose = true;//如果出现异常,标识客户端下线  
  292.                                 sks.ex = new Exception("客户端无连接");  
  293.                                 pushSockets.Invoke(sks);//推送至UI  
  294.   
  295.                             }  
  296.                         }   
  297.                 }  
  298.             }  
  299.             catch(Exception skex)  
  300.             {   
  301.                 Sockets sks = new Sockets();  
  302.                     sks.ClientDispose = true;//如果出现异常,标识客户端退出  
  303.                     sks.ex = skex;  
  304.                     pushSockets.Invoke(sks);//推送至UI  
  305.             }  
  306.         }  
  307.     }  
  308. }  

BXHTcpClient 类 Tcp客户端类

[csharp] view plain copy
  1. /***************************************************** 
  2.  * ProjectName:  BenXHSocket 
  3.  * Description: 
  4.  * ClassName:    BxhTcpClient 
  5.  * CLRVersion:   4.0.30319.42000 
  6.  * Author:       JiYF 
  7.  * NameSpace:    BenXHSocket 
  8.  * MachineName:  JIYF_PC 
  9.  * CreateTime:   2017/3/31 20:31:48 
  10.  * UpdatedTime:  2017/3/31 20:31:48 
  11. *****************************************************/  
  12. using System;  
  13. using System.Collections.Generic;  
  14. using System.Linq;  
  15. using System.Text;  
  16. using System.Net;  
  17. using System.Net.Sockets;  
  18. using System.Threading;  
  19.   
  20. namespace BenXHSocket  
  21. {  
  22.     public class BXHTcpClient : SocketObject  
  23.     {  
  24.             bool IsClose = false;  
  25.   
  26.             /// <summary>  
  27.             /// 当前管理对象  
  28.             /// </summary>  
  29.             Sockets sk;  
  30.   
  31.             /// <summary>  
  32.             /// 客户端  
  33.             /// </summary>  
  34.            public TcpClient client;  
  35.   
  36.             /// <summary>  
  37.             /// 当前连接服务端地址  
  38.             /// </summary>  
  39.             IPAddress Ipaddress;  
  40.   
  41.             /// <summary>  
  42.             /// 当前连接服务端端口号  
  43.             /// </summary>  
  44.             int Port;  
  45.   
  46.             /// <summary>  
  47.             /// 服务端IP+端口  
  48.             /// </summary>  
  49.             IPEndPoint ip;  
  50.   
  51.             /// <summary>  
  52.             /// 发送与接收使用的流  
  53.             /// </summary>  
  54.             NetworkStream nStream;  
  55.           
  56.             
  57.   
  58.             /// <summary>  
  59.             /// 初始化Socket  
  60.             /// </summary>  
  61.             /// <param name="ipaddress"></param>  
  62.             /// <param name="port"></param>  
  63.             public override void InitSocket(string ipaddress, int port)  
  64.             {  
  65.                 Ipaddress = IPAddress.Parse(ipaddress);  
  66.                 Port = port;  
  67.                 ip = new IPEndPoint(Ipaddress, Port);  
  68.                 client = new TcpClient();  
  69.             }  
  70.   
  71.             public static PushSockets pushSockets;  
  72.             public void SendData(string SendData)  
  73.             {  
  74.                 try  
  75.                 {  
  76.   
  77.                     if (client == null || !client.Connected)  
  78.                     {  
  79.                         Sockets sks = new Sockets();  
  80.                         sks.ex = new Exception("客户端无连接..");  
  81.                         sks.ClientDispose = true;  
  82.                           
  83.                         pushSockets.Invoke(sks);//推送至UI   
  84.                     }  
  85.                     if (client.Connected) //如果连接则发送  
  86.                     {  
  87.                         if (nStream == null)  
  88.                         {  
  89.                             nStream = client.GetStream();  
  90.                         }  
  91.                         byte[] buffer = Encoding.UTF8.GetBytes(SendData);  
  92.                         nStream.Write(buffer, 0, buffer.Length);  
  93.                     }  
  94.                 }  
  95.                 catch (Exception skex)  
  96.                 {  
  97.                     Sockets sks = new Sockets();  
  98.                     sks.ex = skex;  
  99.                     sks.ClientDispose = true;  
  100.                     pushSockets.Invoke(sks);//推送至UI  
  101.                 }  
  102.             }  
  103.             /// <summary>  
  104.             /// 初始化Socket  
  105.             /// </summary>  
  106.             /// <param name="ipaddress"></param>  
  107.             /// <param name="port"></param>  
  108.             public override void InitSocket(IPAddress ipaddress, int port)  
  109.             {  
  110.                 Ipaddress = ipaddress;  
  111.                 Port = port;  
  112.                 ip = new IPEndPoint(Ipaddress, Port);  
  113.                 client = new TcpClient();  
  114.             }  
  115.             private void Connect()  
  116.             {  
  117.                 client.Connect(ip);  
  118.                 nStream = new NetworkStream(client.Client, true);  
  119.                 sk = new Sockets(ip, client, nStream);  
  120.                 sk.nStream.BeginRead(sk.RecBuffer, 0, sk.RecBuffer.Length, new AsyncCallback(EndReader), sk);  
  121.             }  
  122.             private void EndReader(IAsyncResult ir)  
  123.             {  
  124.   
  125.                 Sockets s = ir.AsyncState as Sockets;  
  126.                 try  
  127.                 {  
  128.                     if (s != null)  
  129.                     {  
  130.   
  131.                         if (IsClose && client == null)  
  132.                         {  
  133.                             sk.nStream.Close();  
  134.                             sk.nStream.Dispose();  
  135.                             return;  
  136.                         }  
  137.                         s.Offset = s.nStream.EndRead(ir);  
  138.                         pushSockets.Invoke(s);//推送至UI  
  139.                         sk.nStream.BeginRead(sk.RecBuffer, 0, sk.RecBuffer.Length, new AsyncCallback(EndReader), sk);  
  140.                     }  
  141.                 }  
  142.                 catch (Exception skex)  
  143.                 {  
  144.                     Sockets sks = s;  
  145.                     sks.ex = skex;  
  146.                     sks.ClientDispose = true;  
  147.                     pushSockets.Invoke(sks);//推送至UI  
  148.   
  149.                 }  
  150.   
  151.             }  
  152.             /// <summary>  
  153.             /// 重写Start方法,其实就是连接服务端  
  154.             /// </summary>  
  155.             public override void Start()  
  156.             {  
  157.                 Connect();  
  158.             }  
  159.             public override void Stop()  
  160.             {  
  161.                 Sockets sks = new Sockets();  
  162.                 if (client != null)  
  163.                 {  
  164.                     client.Client.Shutdown(SocketShutdown.Both);  
  165.                     Thread.Sleep(10);  
  166.                     client.Close();  
  167.                     IsClose = true;  
  168.                     client = null;  
  169.                 }  
  170.                 else  
  171.                 {  
  172.                     sks.ex = new Exception("客户端没有初始化.!");  
  173.                 }  
  174.                 pushSockets.Invoke(sks);//推送至UI  
  175.             }  
  176.   
  177.         }  
  178. }  

服务端和客户端窗体应用程序主要方法设计实现

服务端窗体应用程序主要方法代码:

[csharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Linq;  
  7. using System.Text;  
  8. using System.Windows.Forms;  
  9. using System.Configuration;  
  10. using System.Net;  
  11. using BenXHSocket;  
  12. using System.Threading;  
  13.   
  14. namespace BenXHSocketTcpServer  
  15. {  
  16.     public partial class FrmTCPServer : Form  
  17.     {  
  18.         private static string serverIP;  
  19.         private static int port;  
  20.         object obj = new object();  
  21.         private int sendInt = 0;  
  22.         private static Dictionary<TreeNode, IPEndPoint> DicTreeIPEndPoint = new Dictionary<TreeNode, IPEndPoint>();  
  23.   
  24.         public FrmTCPServer()  
  25.         {  
  26.             InitializeComponent();  
  27.               
  28.             serverIP = ConfigurationManager.AppSettings["ServerIP"];  
  29.             port = int.Parse(ConfigurationManager.AppSettings["ServerPort"]);  
  30.             Control.CheckForIllegalCrossThreadCalls = false;  
  31.             init();  
  32.         }  
  33.   
  34.         private void init()  
  35.         {  
  36.             treeViewClientList.Nodes.Clear();  
  37.             TreeNode tn = new TreeNode();  
  38.             tn.Name = "ClientList";  
  39.             tn.Text = "客户端列表";  
  40.             tn.ImageIndex = 0;  
  41.             tn.ContextMenuStrip = contextMenuStripClientAll;  
  42.             treeViewClientList.Nodes.Add(tn);  
  43.             DicTreeIPEndPoint.Clear();  
  44.   
  45.             //自已绘制    
  46.             this.treeViewClientList.DrawMode = TreeViewDrawMode.OwnerDrawText;  
  47.             this.treeViewClientList.DrawNode += new DrawTreeNodeEventHandler(treeViewClientList_DrawNode);  
  48.         }  
  49.   
  50.         private BenXHSocket.BXHTcpServer tcpServer;  
  51.   
  52.   
  53.         /// <summary>  
  54.         /// 绘制颜色  
  55.         /// </summary>  
  56.         /// <param name="sender"></param>  
  57.         /// <param name="e"></param>  
  58.         private void treeViewClientList_DrawNode(object sender, DrawTreeNodeEventArgs e)  
  59.         {  
  60.             e.DrawDefault = true//我这里用默认颜色即可,只需要在TreeView失去焦点时选中节点仍然突显    
  61.             return;  
  62.             //or  自定义颜色    
  63.             if ((e.State & TreeNodeStates.Selected) != 0)  
  64.             {  
  65.                 //演示为绿底白字    
  66.                 e.Graphics.FillRectangle(Brushes.DarkBlue, e.Node.Bounds);  
  67.   
  68.                 Font nodeFont = e.Node.NodeFont;  
  69.                 if (nodeFont == null) nodeFont = ((TreeView)sender).Font;  
  70.                 e.Graphics.DrawString(e.Node.Text, nodeFont, Brushes.White, Rectangle.Inflate(e.Bounds, 2, 0));  
  71.             }  
  72.             else  
  73.             {  
  74.                 e.DrawDefault = true;  
  75.             }  
  76.   
  77.             if ((e.State & TreeNodeStates.Focused) != 0)  
  78.             {  
  79.                 using (Pen focusPen = new Pen(Color.Black))  
  80.                 {  
  81.                     focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;  
  82.                     Rectangle focusBounds = e.Node.Bounds;  
  83.                     focusBounds.Size = new Size(focusBounds.Width - 1,  
  84.                     focusBounds.Height - 1);  
  85.                     e.Graphics.DrawRectangle(focusPen, focusBounds);  
  86.                 }  
  87.             }  
  88.   
  89.         }    
  90.   
  91.         /// <summary>  
  92.         /// 开启服务  
  93.         /// </summary>  
  94.         /// <param name="sender"></param>  
  95.         /// <param name="e"></param>  
  96.         private void StartServerToolStripMenuItem_Click(object sender, EventArgs e)  
  97.         {  
  98.             try  
  99.             {  
  100.                 if (serverIP != null && serverIP != "" && port != null && port >= 0)  
  101.                 {  
  102.                     tcpServer.InitSocket(IPAddress.Parse(serverIP), port);  
  103.                     tcpServer.Start();  
  104.                     listBoxServerInfo.Items.Add(string.Format("{0}服务端程序监听启动成功!监听:{1}:{2}",DateTime.Now.ToString(), serverIP, port.ToString()));  
  105.                     StartServerToolStripMenuItem.Enabled = false;  
  106.                 }  
  107.   
  108.                   
  109.             }  
  110.             catch(Exception ex)  
  111.             {  
  112.                 listBoxServerInfo.Items.Add(string.Format("服务器启动失败!原因:{0}",ex.Message));  
  113.                 StartServerToolStripMenuItem.Enabled = true;  
  114.             }  
  115.         }  
  116.   
  117.         /// <summary>  
  118.         /// 停止服务监听  
  119.         /// </summary>  
  120.         /// <param name="sender"></param>  
  121.         /// <param name="e"></param>  
  122.         private void StopServerToolStripMenuItem_Click(object sender, EventArgs e)  
  123.         {  
  124.             tcpServer.Stop();  
  125.             listBoxServerInfo.Items.Add("服务器程序停止成功!");  
  126.             StartServerToolStripMenuItem.Enabled = true;  
  127.              
  128.         }  
  129.   
  130.         private void FrmTCPServer_Load(object sender, EventArgs e)  
  131.         {  
  132.             if(tcpServer ==null)  
  133.             listBoxServerInfo.Items.Add(string.Format("服务端监听程序尚未开启!{0}:{1}",serverIP,port));  
  134.             treeViewClientList.ExpandAll();  
  135.             BXHTcpServer.pushSockets = new PushSockets(Rev);  
  136.             tcpServer = new BXHTcpServer();  
  137.         }  
  138.   
  139.         /// <summary>  
  140.         /// 处理接收到客户端的请求和数据  
  141.         /// </summary>  
  142.         /// <param name="sks"></param>  
  143.         private void Rev(BenXHSocket.Sockets sks)  
  144.         {  
  145.             this.Invoke(new ThreadStart(  
  146.                 delegate  
  147.                 {  
  148.                     if (treeViewClientList.Nodes[0] != null)  
  149.                     {   
  150.                           
  151.                     }  
  152.   
  153.                     if (sks.ex != null)  
  154.                     {  
  155.                         if (sks.ClientDispose)  
  156.                         {  
  157.                             listBoxServerInfo.Items.Add(string.Format("{0}客户端:{1}下线!",DateTime.Now.ToString(), sks.Ip));  
  158.                             if (treeViewClientList.Nodes[0].Nodes.ContainsKey(sks.Ip.ToString()))  
  159.                             {  
  160.                                 if (DicTreeIPEndPoint.Count != 0)  
  161.                                 {  
  162.                                     removTreeIPEndPoint(sks.Ip);  
  163.                                     treeViewClientList.Nodes[0].Nodes.RemoveByKey(sks.Ip.ToString());  
  164.   
  165.                                     toolStripStatusLabelClientNum.Text = (int.Parse(toolStripStatusLabelClientNum.Text) - 1).ToString();//treeViewClientList.Nodes[0].Nodes.Count.ToString();  
  166.                              
  167.                                 }  
  168.                                  
  169.                                }  
  170.                         }  
  171.                         listBoxServerInfo.Items.Add(sks.ex.Message);  
  172.                     }  
  173.                     else  
  174.                     {  
  175.                         if (sks.NewClientFlag)  
  176.                         {  
  177.                             listBoxServerInfo.Items.Add(string.Format("{0}新的客户端:{0}链接成功",DateTime.Now.ToString(), sks.Ip));  
  178.                               
  179.                             TreeNode tn = new TreeNode();  
  180.                             tn.Name = sks.Ip.ToString();  
  181.                             tn.Text = sks.Ip.ToString();  
  182.                             tn.ContextMenuStrip = contextMenuStripClientSingle;  
  183.                             tn.Tag = "客户端";  
  184.                             tn.ImageIndex = 1;  
  185.   
  186.                             treeViewClientList.Nodes[0].Nodes.Add(tn);  
  187.   
  188.                             //treeview节点和IPEndPoint绑定  
  189.                             DicTreeIPEndPoint.Add(tn,sks.Ip);  
  190.   
  191.                             if (treeViewClientList.Nodes[0].Nodes.Count > 0)  
  192.                             {  
  193.                                 treeViewClientList.ExpandAll();  
  194.                             }  
  195.                             toolStripStatusLabelClientNum.Text = (int.Parse(toolStripStatusLabelClientNum.Text)+1).ToString();  
  196.                         }  
  197.                         else if (sks.Offset == 0)  
  198.                         {  
  199.                             listBoxServerInfo.Items.Add(string.Format("{0}客户端:{1}下线.!",DateTime.Now.ToString(), sks.Ip));  
  200.                             if (treeViewClientList.Nodes[0].Nodes.ContainsKey(sks.Ip.ToString()))  
  201.                             {  
  202.                                 if (DicTreeIPEndPoint.Count != 0)  
  203.                                 {  
  204.                                     removTreeIPEndPoint(sks.Ip);  
  205.                                     treeViewClientList.Nodes[0].Nodes.RemoveByKey(sks.Ip.ToString());  
  206.   
  207.                                     toolStripStatusLabelClientNum.Text = (int.Parse(toolStripStatusLabelClientNum.Text) - 1).ToString();  
  208.                               
  209.                                 }  
  210.                             }  
  211.                         }  
  212.                         else  
  213.                         {  
  214.                             byte[] buffer = new byte[sks.Offset];  
  215.                             Array.Copy(sks.RecBuffer, buffer, sks.Offset);  
  216.                             string str = Encoding.UTF8.GetString(buffer);  
  217.                             listBox1.Items.Add(string.Format("{0}客户端{1}发来消息:{2}",DateTime.Now.ToString(), sks.Ip, str));  
  218.                         }  
  219.                     }  
  220.                 }  
  221.                 )  
  222.                 );  
  223.         }  
  224.   
  225.         /// <summary>  
  226.         /// 关闭程序钱停止服务器实例  
  227.         /// </summary>  
  228.         /// <param name="sender"></param>  
  229.         /// <param name="e"></param>  
  230.         private void FrmTCPServer_FormClosing(object sender, FormClosingEventArgs e)  
  231.         {  
  232.             tcpServer.Stop();  
  233.         }  
  234.   
  235.         private void treeViewClientList_AfterSelect(object sender, TreeViewEventArgs e)  
  236.         {  
  237.             //  
  238.         }  
  239.   
  240.         private void treeViewClientList_MouseClick(object sender, MouseEventArgs e)  
  241.         {  
  242.             if (e.Button == MouseButtons.Right)  
  243.             {  
  244.                 treeViewClientList.Focus();  
  245.                 treeViewClientList.SelectedNode = treeViewClientList.GetNodeAt(e.X,e.Y);  
  246.             }  
  247.   
  248.         }  
  249.   
  250.   
  251.         private void toolStripMenuSendSingle_Click(object sender, EventArgs e)  
  252.         {  
  253.             if (treeViewClientList.SelectedNode != null)  
  254.             {  
  255.                 tcpServer.SendToClient(DicTreeIPEndPoint[treeViewClientList.SelectedNode], string.Format("服务端单个消息...{0}", sendInt.ToString()));  
  256.                 sendInt++;  
  257.             }  
  258.         }  
  259.   
  260.         private void toolStripMenuSendAll_Click(object sender, EventArgs e)  
  261.         {  
  262.             tcpServer.SendToAll("服务端全部发送消息..." + sendInt);  
  263.             sendInt++;  
  264.         }  
  265.   
  266.         private void removTreeIPEndPoint(IPEndPoint ipendPoint)  
  267.         {  
  268.   
  269.             if (DicTreeIPEndPoint.Count <= 0) return;  
  270.             //foreach遍历Dictionary时候不能对字典进行Remove  
  271.             TreeNode[] keys = new TreeNode[DicTreeIPEndPoint.Count];  
  272.             DicTreeIPEndPoint.Keys.CopyTo(keys,0);  
  273.             lock (obj)  
  274.             {  
  275.                 foreach (TreeNode item in keys)  
  276.                 {  
  277.                     if (DicTreeIPEndPoint[item] == ipendPoint)  
  278.                     {  
  279.                         DicTreeIPEndPoint.Remove(item);  
  280.                     }  
  281.                 }  
  282.             }  
  283.         }  
  284.   
  285.     }  
  286. }  

客户端窗体应用程序主要代码

[csharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Linq;  
  7. using System.Text;  
  8. using System.Windows.Forms;  
  9. using System.Net;  
  10. using System.Net.Sockets;  
  11. using BenXHSocket;  
  12. using System.Threading;  
  13.   
  14. namespace BenXHSocketClient  
  15. {  
  16.     public partial class FrmTCPClient : Form  
  17.     {  
  18.         BXHTcpClient tcpClient;  
  19.           
  20.         string ip = string.Empty;  
  21.         string port = string.Empty;  
  22.         private int sendInt = 0;  
  23.         public FrmTCPClient()  
  24.         {  
  25.             InitializeComponent();  
  26.             Control.CheckForIllegalCrossThreadCalls = false;  
  27.         }  
  28.   
  29.         private void btnConnServer_Click(object sender, EventArgs e)  
  30.         {  
  31.             try  
  32.             {  
  33.                 this.ip = txtServerIP.Text.Trim();  
  34.                 this.port = txtServerPort.Text.Trim();  
  35.   
  36.                 tcpClient.InitSocket(ip, int.Parse(port));  
  37.                 tcpClient.Start();  
  38.                 listBoxStates.Items.Add("连接成功!");  
  39.                 btnConnServer.Enabled = false;  
  40.   
  41.             }  
  42.             catch (Exception ex)  
  43.             {  
  44.   
  45.                 listBoxStates.Items.Add(string.Format("连接失败!原因:{0}", ex.Message));  
  46.                 btnConnServer.Enabled = true;  
  47.             }  
  48.         }  
  49.   
  50.         private void FrmTCPClient_Load(object sender, EventArgs e)  
  51.         {  
  52.             //客户端如何处理异常等信息参照服务端  
  53.            
  54.             BXHTcpClient.pushSockets = new PushSockets(Rec);  
  55.   
  56.             tcpClient = new BXHTcpClient();  
  57.             this.ip = txtServerIP.Text.Trim();  
  58.             this.port = txtServerPort.Text.Trim();  
  59.             
  60.         }  
  61.   
  62.         /// <summary>  
  63.         /// 处理推送过来的消息  
  64.         /// </summary>  
  65.         /// <param name="rec"></param>  
  66.         private void Rec(BenXHSocket.Sockets sks)  
  67.         {  
  68.             this.Invoke(new ThreadStart(delegate  
  69.             {  
  70.                 if (listBoxText.Items.Count > 1000)  
  71.                 {  
  72.                     listBoxText.Items.Clear();  
  73.                 }  
  74.                 if (sks.ex != null)  
  75.                 {  
  76.                     if (sks.ClientDispose == true)  
  77.                     {  
  78.                         //由于未知原因引发异常.导致客户端下线.   比如网络故障.或服务器断开连接.  
  79.                         listBoxStates.Items.Add(string.Format("客户端下线.!"));  
  80.                     }  
  81.                     listBoxStates.Items.Add(string.Format("异常消息:{0}", sks.ex));  
  82.                 }  
  83.                 else if (sks.Offset == 0)  
  84.                 {  
  85.                     //客户端主动下线  
  86.                     listBoxStates.Items.Add(string.Format("客户端下线.!"));  
  87.                 }  
  88.                 else  
  89.                 {  
  90.                     byte[] buffer = new byte[sks.Offset];  
  91.                     Array.Copy(sks.RecBuffer, buffer, sks.Offset);  
  92.                     string str = Encoding.UTF8.GetString(buffer);  
  93.                     listBoxText.Items.Add(string.Format("服务端{0}发来消息:{1}", sks.Ip, str));  
  94.                 }  
  95.             }));  
  96.         }  
  97.   
  98.         private void btnDisConn_Click(object sender, EventArgs e)  
  99.         {  
  100.             tcpClient.Stop();  
  101.             btnConnServer.Enabled = true;  
  102.         }  
  103.   
  104.         private void btnSendData_Click(object sender, EventArgs e)  
  105.         {  
  106.             tcpClient.SendData("客户端消息!" + sendInt);  
  107.             sendInt++;  
  108.               
  109.         }  
  110.   
  111.         private void btnConnTest_Click(object sender, EventArgs e)  
  112.         {  
  113.             ThreadPool.QueueUserWorkItem(o =>  
  114.             {  
  115.                 for (int i = 0; i < 100; i++)  
  116.                 {  
  117.                     BenXHSocket.BXHTcpClient clientx= new  BenXHSocket.BXHTcpClient();//初始化类库    
  118.                     clientx.InitSocket(ip, int.Parse(port));  
  119.                     clientx.Start();  
  120.                 }  
  121.                 MessageBox.Show("完成.!");  
  122.             });  
  123.         }  
  124.   
  125.   
  126.     }  
  127. }  

运行程序下载:

BenXHSocket程序下载 

源代码工程文件下载

内容:

BenXHSocket.dll      主要程序动态库

BenXHSocketClient.exe   客户端应用程序

BenXHSocketTcpServer.exe  服务端应用程序

BenXHSocketTcpServer.exe.config  服务端应用程序配置文件

其中:BenXHSocketTcpServer.exe.config为配置文件,可以设置监听的ip地址和端口号,默认ip地址:127.0.0.1 默认的端口号:4455

 


原创粉丝点击