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

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

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

只实现了TCP通信

通信程序截图:

压力测试服务端截图:

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

服务端:

客户端

运行动态图

C#程序设计代码

BenXHSocket.dll主要代码设计

SocketObject类

 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 }
View Code

sockets类

 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 { get; set; }
42         /// <summary>
43         /// 客户端主通信程序
44         /// </summary>
45         public TcpClient Client { get; set; }
46         /// <summary>
47         /// 承载客户端Socket的网络流
48         /// </summary>
49         public NetworkStream nStream { get; set; }
50 
51         /// <summary>
52         /// 发生异常时不为null.
53         /// </summary>
54         public Exception ex { get; set; }
55 
56         /// <summary>
57         /// 新客户端标识.如果推送器发现此标识为true,那么认为是客户端上线
58         /// 仅服务端有效
59         /// </summary>
60         public bool NewClientFlag { get; set; }
61 
62         /// <summary>
63         /// 客户端退出标识.如果服务端发现此标识为true,那么认为客户端下线
64         /// 客户端接收此标识时,认为客户端异常.
65         /// </summary>
66         public bool ClientDispose { get; set; }
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 }
View Code

SocketsHandler类

 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 }
View Code

BXHTcpServer类 tcp服务端监听类

  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 }
View Code

BXHTcpClient 类 Tcp客户端类

  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 }
View Code

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

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

  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 }
View Code

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

  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 }
View Code

运行程序下载:

BenXHSocket程序下载 

源代码工程文件下载

内容:

BenXHSocket.dll      主要程序动态库

BenXHSocketClient.exe   客户端应用程序

BenXHSocketTcpServer.exe  服务端应用程序

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

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

 

 

下载地址:https://files.cnblogs.com/files/JiYF/BenXHSocket.rar

 

 

源代码地址:https://files-cdn.cnblogs.com/files/JiYF/BenXHSocketCode.zip

posted @ 2017-04-12 14:35  JiYF  阅读(7759)  评论(16编辑  收藏  举报