zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    10.18.2 linux文件压缩与打包
    动态代理与静态代理的区别
    JAVA的Date类与Calendar类
    【面试题001】类型转换关键字,空类对象模型,拷贝构造函数,赋值运算符函数
    【面试题001】类型转换关键字,空类对象模型,拷贝构造函数,赋值运算符函数
    j2EE经典面试题
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/JiYF/p/6699104.html
Copyright © 2011-2022 走看看