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

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

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

只实现了TCP通信

通信程序截图:

压力测试服务端截图:

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

服务端:

客户端

运行动态图

C#程序设计代码

BenXHSocket.dll主要代码设计

SocketObject类

/*****************************************************
 * ProjectName:  BenXHSocket
 * Description:
 * ClassName:    SocketObject
 * CLRVersion:   4.0.30319.18408
 * Author:       JiYF
 * NameSpace:    BenXHSocket
 * MachineName:  JIYONGFEI
 * CreateTime:   2017/3/31 12:13:06
 * UpdatedTime:  2017/3/31 12:13:06
*****************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;

namespace BenXHSocket
{
    /// <summary>
    /// Socket基础类
    /// </summary>
    public abstract class SocketObject
    {
        /// <summary>
        /// 初始化Socket方法
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <param name="port"></param>
        public abstract void InitSocket(IPAddress ipAddress,int port);
        public abstract void InitSocket(string ipAddress,int port);

        /// <summary>
        /// Socket启动方法
        /// </summary>
        public abstract void Start();

        /// <summary>
        /// Sockdet停止方法
        /// </summary>
        public abstract void Stop();

    }
}

sockets类

/*****************************************************
 * ProjectName:  BenXHSocket
 * Description:
 * ClassName:    Sockets
 * CLRVersion:   4.0.30319.18408
 * Author:       JiYF
 * NameSpace:    BenXHSocket
 * MachineName:  JIYONGFEI
 * CreateTime:   2017/3/31 12:16:10
 * UpdatedTime:  2017/3/31 12:16:10
*****************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace BenXHSocket
{
    public class Sockets
    {
        /// <summary>
        /// 接收缓冲区大小8k
        /// </summary>
        public byte[] RecBuffer = new byte[8 * 1024]; 
 
        /// <summary>
        /// 发送缓冲区大小8k
        /// </summary>
        public byte[] SendBuffer = new byte[8 * 1024];

        /// <summary>
        /// 异步接收后包的大小
        /// </summary>
        public int Offset { get;set;}

        /// <summary>
        /// 当前IP地址,端口号
        /// </summary>
        public IPEndPoint Ip { get; set; }
        /// <summary>
        /// 客户端主通信程序
        /// </summary>
        public TcpClient Client { get; set; }
        /// <summary>
        /// 承载客户端Socket的网络流
        /// </summary>
        public NetworkStream nStream { get; set; }

        /// <summary>
        /// 发生异常时不为null.
        /// </summary>
        public Exception ex { get; set; }

        /// <summary>
        /// 新客户端标识.如果推送器发现此标识为true,那么认为是客户端上线
        /// 仅服务端有效
        /// </summary>
        public bool NewClientFlag { get; set; }

        /// <summary>
        /// 客户端退出标识.如果服务端发现此标识为true,那么认为客户端下线
        /// 客户端接收此标识时,认为客户端异常.
        /// </summary>
        public bool ClientDispose { get; set; }

        /// <summary>
        /// 空参构造
        /// </summary>
        public Sockets() { }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ip">ip节点</param>
        /// <param name="client">TCPClient客户端</param>
        /// <param name="ns">NetworkStream </param>
        public Sockets(IPEndPoint ip,TcpClient client,NetworkStream ns)
        {
            this.Ip = ip;
            this.Client = client;
            this.nStream = ns;
        }
    }
}
SocketsHandler类
/*****************************************************
 * ProjectName:  BenXHSocket
 * Description:
 * ClassName:    SocketsHandler
 * CLRVersion:   4.0.30319.18408
 * Author:       JiYF
 * NameSpace:    BenXHSocket
 * MachineName:  JIYONGFEI
 * CreateTime:   2017/3/31 13:42:48
 * UpdatedTime:  2017/3/31 13:42:48
*****************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BenXHSocket
{
    /// <summary>
    /// 推送器
    /// </summary>
    /// <param name="sockets"></param>
    public delegate void PushSockets(Sockets sockets);
    
}

BXHTcpServer类 tcp服务端监听类

/*****************************************************
 * ProjectName:  BenXHSocket
 * Description:
 * ClassName:    TcpServer
 * CLRVersion:   4.0.30319.18408
 * Author:       JiYF
 * NameSpace:    BenXHSocket
 * MachineName:  JIYONGFEI
 * CreateTime:   2017/3/31 12:24:08
 * UpdatedTime:  2017/3/31 12:24:08
*****************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace BenXHSocket
{
    /// <summary>
    /// TCPServer类 服务端程序
    /// </summary>
    public class BXHTcpServer:SocketObject
    {
        private bool IsStop = false;
        object obj = new object();
        public static PushSockets pushSockets;

        /// <summary>
        /// 信号量
        /// </summary>
        private Semaphore semap = new Semaphore(5,5000);

        /// <summary>
        /// 客户端列表集合
        /// </summary>
        public List<Sockets> ClientList = new List<Sockets>();

        /// <summary>
        /// 服务端实例对象
        /// </summary>
        public TcpListener Listener;

        /// <summary>
        /// 当前的ip地址
        /// </summary>
        private IPAddress IpAddress;

        /// <summary>
        /// 初始化消息
        /// </summary>
        private string InitMsg = "JiYF笨小孩TCP服务端";

        /// <summary>
        /// 监听的端口
        /// </summary>
        private int Port;

        /// <summary>
        /// 当前ip和端口节点对象
        /// </summary>
        private IPEndPoint Ip;


        /// <summary>
        /// 初始化服务器对象
        /// </summary>
        /// <param name="ipAddress">IP地址</param>
        /// <param name="port">端口号</param>
        public override void InitSocket(IPAddress ipAddress, int port)
        {
            this.IpAddress = ipAddress;
            this.Port = port;
            this.Listener = new TcpListener(IpAddress,Port);
        }

        /// <summary>
        /// 初始化服务器对象
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <param name="port"></param>
        public override void InitSocket(string ipAddress, int port)
        {
            this.IpAddress = IPAddress.Parse(ipAddress);
            this.Port = port;
            this.Ip = new IPEndPoint(IpAddress,Port);
            this.Listener = new TcpListener(IpAddress,Port);
        }

        /// <summary>
        /// 服务端启动监听,处理链接
        /// </summary>
        public override void Start()
        {
            try
            { 
                Listener.Start();
                Thread Accth = new Thread(new ThreadStart(
                    delegate
                    {
                        while(true)
                        {
                            if(IsStop != false)
                            {
                                break;
                            }
                            this.GetAcceptTcpClient();
                            Thread.Sleep(1);
                        }
                    }
                    ));
                Accth.Start();
            }
            catch(SocketException skex)
            {
                Sockets sks = new Sockets();
                sks.ex = skex;
                pushSockets.Invoke(sks);
            }
        }

        /// <summary>
        /// 获取处理新的链接请求
        /// </summary>
        private void GetAcceptTcpClient()
        {
            try
            { 
                if(Listener.Pending())
                {
                    semap.WaitOne();
                    //接收到挂起的客户端请求链接
                    TcpClient tcpClient = Listener.AcceptTcpClient();

                    //维护处理客户端队列
                    Socket socket = tcpClient.Client;
                    NetworkStream stream = new NetworkStream(socket,true);
                    Sockets sks = new Sockets(tcpClient.Client.RemoteEndPoint as IPEndPoint,tcpClient,stream);
                    sks.NewClientFlag = true;

                    //推送新的客户端连接信息
                    pushSockets.Invoke(sks);

                    //客户端异步接收数据
                    sks.nStream.BeginRead(sks.RecBuffer,0,sks.RecBuffer.Length,new AsyncCallback(EndReader),sks);
                    
                    //加入客户端队列
                    this.AddClientList(sks);

                    //链接成功后主动向客户端发送一条消息
                    if(stream.CanWrite)
                    {
                        byte[] buffer = Encoding.UTF8.GetBytes(this.InitMsg);
                        stream.Write(buffer, 0, buffer.Length);
                    }
                    semap.Release();
                }
            }
            catch
            {
                return;
            }
        }

        /// <summary>
        /// 异步接收发送的的信息
        /// </summary>
        /// <param name="ir"></param>
        private void EndReader(IAsyncResult ir)
        {
            Sockets sks = ir.AsyncState as Sockets;
            if (sks != null && Listener != null)
            {
                try
                {
                    if (sks.NewClientFlag || sks.Offset != 0)
                    {
                        sks.NewClientFlag = false;
                        sks.Offset = sks.nStream.EndRead(ir);
                        //推送到UI
                        pushSockets.Invoke(sks);
                        sks.nStream.BeginRead(sks.RecBuffer,0,sks.RecBuffer.Length,new AsyncCallback(EndReader),sks);
                    }
                }
                catch(Exception skex)
                {
                    lock (obj)
                    {
                        ClientList.Remove(sks);
                        Sockets sk = sks;
                        //标记客户端退出程序
                        sk.ClientDispose = true;
                        sk.ex = skex;
                        //推送至UI
                        pushSockets.Invoke(sks);
                    }
                }
            }
        }

        /// <summary>
        /// 客户端加入队列
        /// </summary>
        /// <param name="sk"></param>
        private void AddClientList(Sockets sk)
        {
            lock (obj)
            {
                Sockets sockets = ClientList.Find(o => { return o.Ip == sk.Ip; });
                if (sockets == null)
                {
                    ClientList.Add(sk);
                }
                else
                {
                    ClientList.Remove(sockets);
                    ClientList.Add(sk);
                }
            }
        }

        /// <summary>
        /// 服务端停止监听
        /// </summary>
        public override void Stop()
        {
            if (Listener != null)
            {
                Listener.Stop();
                Listener = null;
                IsStop = true;
                pushSockets = null;
            }
        }

        /// <summary>
        /// 向所有在线客户端发送消息
        /// </summary>
        /// <param name="SendData">消息内容</param>
        public void SendToAll(string SendData)
        {
            for (int i = 0; i < ClientList.Count; i++)
            {
                SendToClient(ClientList[i].Ip, SendData);
            }
        }

        /// <summary>
        /// 向单独的一个客户端发送消息
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="SendData"></param>
        public void SendToClient(IPEndPoint ip,string SendData)
        {
            try
            {
                Sockets sks = ClientList.Find(o => { return o.Ip == ip; });
                if(sks == null || !sks.Client.Connected)
                {
                    Sockets ks = new Sockets();
                    //标识客户端下线
                    sks.ClientDispose = true;
                    sks.ex = new Exception("客户端没有连接");
                    pushSockets.Invoke(sks);
                }
                if(sks.Client.Connected)
                {
                     //获取当前流进行写入.
                        NetworkStream nStream = sks.nStream;
                        if (nStream.CanWrite)
                        {
                            byte[] buffer = Encoding.UTF8.GetBytes(SendData);
                            nStream.Write(buffer, 0, buffer.Length);
                        }
                        else
                        {
                            //避免流被关闭,重新从对象中获取流
                            nStream = sks.Client.GetStream();
                            if (nStream.CanWrite)
                            {
                                byte[] buffer = Encoding.UTF8.GetBytes(SendData);
                                nStream.Write(buffer, 0, buffer.Length);
                            }
                            else
                            {
                                //如果还是无法写入,那么认为客户端中断连接.
                                ClientList.Remove(sks);
                                Sockets ks = new Sockets();
                                sks.ClientDispose = true;//如果出现异常,标识客户端下线
                                sks.ex = new Exception("客户端无连接");
                                pushSockets.Invoke(sks);//推送至UI

                            }
                        } 
                }
            }
            catch(Exception skex)
            { 
                Sockets sks = new Sockets();
                    sks.ClientDispose = true;//如果出现异常,标识客户端退出
                    sks.ex = skex;
                    pushSockets.Invoke(sks);//推送至UI
            }
        }
    }
}

BXHTcpClient 类 Tcp客户端类

/*****************************************************
 * ProjectName:  BenXHSocket
 * Description:
 * ClassName:    BxhTcpClient
 * CLRVersion:   4.0.30319.42000
 * Author:       JiYF
 * NameSpace:    BenXHSocket
 * MachineName:  JIYF_PC
 * CreateTime:   2017/3/31 20:31:48
 * UpdatedTime:  2017/3/31 20:31:48
*****************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace BenXHSocket
{
    public class BXHTcpClient : SocketObject
    {
            bool IsClose = false;

            /// <summary>
            /// 当前管理对象
            /// </summary>
            Sockets sk;

            /// <summary>
            /// 客户端
            /// </summary>
           public TcpClient client;

            /// <summary>
            /// 当前连接服务端地址
            /// </summary>
            IPAddress Ipaddress;

            /// <summary>
            /// 当前连接服务端端口号
            /// </summary>
            int Port;

            /// <summary>
            /// 服务端IP+端口
            /// </summary>
            IPEndPoint ip;

            /// <summary>
            /// 发送与接收使用的流
            /// </summary>
            NetworkStream nStream;
        
          

            /// <summary>
            /// 初始化Socket
            /// </summary>
            /// <param name="ipaddress"></param>
            /// <param name="port"></param>
            public override void InitSocket(string ipaddress, int port)
            {
                Ipaddress = IPAddress.Parse(ipaddress);
                Port = port;
                ip = new IPEndPoint(Ipaddress, Port);
                client = new TcpClient();
            }

            public static PushSockets pushSockets;
            public void SendData(string SendData)
            {
                try
                {

                    if (client == null || !client.Connected)
                    {
                        Sockets sks = new Sockets();
                        sks.ex = new Exception("客户端无连接..");
                        sks.ClientDispose = true;
                        
                        pushSockets.Invoke(sks);//推送至UI 
                    }
                    if (client.Connected) //如果连接则发送
                    {
                        if (nStream == null)
                        {
                            nStream = client.GetStream();
                        }
                        byte[] buffer = Encoding.UTF8.GetBytes(SendData);
                        nStream.Write(buffer, 0, buffer.Length);
                    }
                }
                catch (Exception skex)
                {
                    Sockets sks = new Sockets();
                    sks.ex = skex;
                    sks.ClientDispose = true;
                    pushSockets.Invoke(sks);//推送至UI
                }
            }
            /// <summary>
            /// 初始化Socket
            /// </summary>
            /// <param name="ipaddress"></param>
            /// <param name="port"></param>
            public override void InitSocket(IPAddress ipaddress, int port)
            {
                Ipaddress = ipaddress;
                Port = port;
                ip = new IPEndPoint(Ipaddress, Port);
                client = new TcpClient();
            }
            private void Connect()
            {
                client.Connect(ip);
                nStream = new NetworkStream(client.Client, true);
                sk = new Sockets(ip, client, nStream);
                sk.nStream.BeginRead(sk.RecBuffer, 0, sk.RecBuffer.Length, new AsyncCallback(EndReader), sk);
            }
            private void EndReader(IAsyncResult ir)
            {

                Sockets s = ir.AsyncState as Sockets;
                try
                {
                    if (s != null)
                    {

                        if (IsClose && client == null)
                        {
                            sk.nStream.Close();
                            sk.nStream.Dispose();
                            return;
                        }
                        s.Offset = s.nStream.EndRead(ir);
                        pushSockets.Invoke(s);//推送至UI
                        sk.nStream.BeginRead(sk.RecBuffer, 0, sk.RecBuffer.Length, new AsyncCallback(EndReader), sk);
                    }
                }
                catch (Exception skex)
                {
                    Sockets sks = s;
                    sks.ex = skex;
                    sks.ClientDispose = true;
                    pushSockets.Invoke(sks);//推送至UI

                }

            }
            /// <summary>
            /// 重写Start方法,其实就是连接服务端
            /// </summary>
            public override void Start()
            {
                Connect();
            }
            public override void Stop()
            {
                Sockets sks = new Sockets();
                if (client != null)
                {
                    client.Client.Shutdown(SocketShutdown.Both);
                    Thread.Sleep(10);
                    client.Close();
                    IsClose = true;
                    client = null;
                }
                else
                {
                    sks.ex = new Exception("客户端没有初始化.!");
                }
                pushSockets.Invoke(sks);//推送至UI
            }

        }
}

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

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

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Net;
using BenXHSocket;
using System.Threading;

namespace BenXHSocketTcpServer
{
    public partial class FrmTCPServer : Form
    {
        private static string serverIP;
        private static int port;
        object obj = new object();
        private int sendInt = 0;
        private static Dictionary<TreeNode, IPEndPoint> DicTreeIPEndPoint = new Dictionary<TreeNode, IPEndPoint>();

        public FrmTCPServer()
        {
            InitializeComponent();
            
            serverIP = ConfigurationManager.AppSettings["ServerIP"];
            port = int.Parse(ConfigurationManager.AppSettings["ServerPort"]);
            Control.CheckForIllegalCrossThreadCalls = false;
            init();
        }

        private void init()
        {
            treeViewClientList.Nodes.Clear();
            TreeNode tn = new TreeNode();
            tn.Name = "ClientList";
            tn.Text = "客户端列表";
            tn.ImageIndex = 0;
            tn.ContextMenuStrip = contextMenuStripClientAll;
            treeViewClientList.Nodes.Add(tn);
            DicTreeIPEndPoint.Clear();

            //自已绘制  
            this.treeViewClientList.DrawMode = TreeViewDrawMode.OwnerDrawText;
            this.treeViewClientList.DrawNode += new DrawTreeNodeEventHandler(treeViewClientList_DrawNode);
        }

        private BenXHSocket.BXHTcpServer tcpServer;


        /// <summary>
        /// 绘制颜色
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeViewClientList_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {
            e.DrawDefault = true; //我这里用默认颜色即可,只需要在TreeView失去焦点时选中节点仍然突显  
            return;
            //or  自定义颜色  
            if ((e.State & TreeNodeStates.Selected) != 0)
            {
                //演示为绿底白字  
                e.Graphics.FillRectangle(Brushes.DarkBlue, e.Node.Bounds);

                Font nodeFont = e.Node.NodeFont;
                if (nodeFont == null) nodeFont = ((TreeView)sender).Font;
                e.Graphics.DrawString(e.Node.Text, nodeFont, Brushes.White, Rectangle.Inflate(e.Bounds, 2, 0));
            }
            else
            {
                e.DrawDefault = true;
            }

            if ((e.State & TreeNodeStates.Focused) != 0)
            {
                using (Pen focusPen = new Pen(Color.Black))
                {
                    focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                    Rectangle focusBounds = e.Node.Bounds;
                    focusBounds.Size = new Size(focusBounds.Width - 1,
                    focusBounds.Height - 1);
                    e.Graphics.DrawRectangle(focusPen, focusBounds);
                }
            }

        }  

        /// <summary>
        /// 开启服务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (serverIP != null && serverIP != "" && port != null && port >= 0)
                {
                    tcpServer.InitSocket(IPAddress.Parse(serverIP), port);
                    tcpServer.Start();
                    listBoxServerInfo.Items.Add(string.Format("{0}服务端程序监听启动成功!监听:{1}:{2}",DateTime.Now.ToString(), serverIP, port.ToString()));
                    StartServerToolStripMenuItem.Enabled = false;
                }

                
            }
            catch(Exception ex)
            {
                listBoxServerInfo.Items.Add(string.Format("服务器启动失败!原因:{0}",ex.Message));
                StartServerToolStripMenuItem.Enabled = true;
            }
        }

        /// <summary>
        /// 停止服务监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StopServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tcpServer.Stop();
            listBoxServerInfo.Items.Add("服务器程序停止成功!");
            StartServerToolStripMenuItem.Enabled = true;
           
        }

        private void FrmTCPServer_Load(object sender, EventArgs e)
        {
            if(tcpServer ==null)
            listBoxServerInfo.Items.Add(string.Format("服务端监听程序尚未开启!{0}:{1}",serverIP,port));
            treeViewClientList.ExpandAll();
            BXHTcpServer.pushSockets = new PushSockets(Rev);
            tcpServer = new BXHTcpServer();
        }

        /// <summary>
        /// 处理接收到客户端的请求和数据
        /// </summary>
        /// <param name="sks"></param>
        private void Rev(BenXHSocket.Sockets sks)
        {
            this.Invoke(new ThreadStart(
                delegate
                {
                    if (treeViewClientList.Nodes[0] != null)
                    { 
                        
                    }

                    if (sks.ex != null)
                    {
                        if (sks.ClientDispose)
                        {
                            listBoxServerInfo.Items.Add(string.Format("{0}客户端:{1}下线!",DateTime.Now.ToString(), sks.Ip));
                            if (treeViewClientList.Nodes[0].Nodes.ContainsKey(sks.Ip.ToString()))
                            {
                                if (DicTreeIPEndPoint.Count != 0)
                                {
                                    removTreeIPEndPoint(sks.Ip);
                                    treeViewClientList.Nodes[0].Nodes.RemoveByKey(sks.Ip.ToString());

                                    toolStripStatusLabelClientNum.Text = (int.Parse(toolStripStatusLabelClientNum.Text) - 1).ToString();//treeViewClientList.Nodes[0].Nodes.Count.ToString();
                           
                                }
                               
                               }
                        }
                        listBoxServerInfo.Items.Add(sks.ex.Message);
                    }
                    else
                    {
                        if (sks.NewClientFlag)
                        {
                            listBoxServerInfo.Items.Add(string.Format("{0}新的客户端:{0}链接成功",DateTime.Now.ToString(), sks.Ip));
                            
                            TreeNode tn = new TreeNode();
                            tn.Name = sks.Ip.ToString();
                            tn.Text = sks.Ip.ToString();
                            tn.ContextMenuStrip = contextMenuStripClientSingle;
                            tn.Tag = "客户端";
                            tn.ImageIndex = 1;

                            treeViewClientList.Nodes[0].Nodes.Add(tn);

                            //treeview节点和IPEndPoint绑定
                            DicTreeIPEndPoint.Add(tn,sks.Ip);

                            if (treeViewClientList.Nodes[0].Nodes.Count > 0)
                            {
                                treeViewClientList.ExpandAll();
                            }
                            toolStripStatusLabelClientNum.Text = (int.Parse(toolStripStatusLabelClientNum.Text)+1).ToString();
                        }
                        else if (sks.Offset == 0)
                        {
                            listBoxServerInfo.Items.Add(string.Format("{0}客户端:{1}下线.!",DateTime.Now.ToString(), sks.Ip));
                            if (treeViewClientList.Nodes[0].Nodes.ContainsKey(sks.Ip.ToString()))
                            {
                                if (DicTreeIPEndPoint.Count != 0)
                                {
                                    removTreeIPEndPoint(sks.Ip);
                                    treeViewClientList.Nodes[0].Nodes.RemoveByKey(sks.Ip.ToString());

                                    toolStripStatusLabelClientNum.Text = (int.Parse(toolStripStatusLabelClientNum.Text) - 1).ToString();
                            
                                }
                            }
                        }
                        else
                        {
                            byte[] buffer = new byte[sks.Offset];
                            Array.Copy(sks.RecBuffer, buffer, sks.Offset);
                            string str = Encoding.UTF8.GetString(buffer);
                            listBox1.Items.Add(string.Format("{0}客户端{1}发来消息:{2}",DateTime.Now.ToString(), sks.Ip, str));
                        }
                    }
                }
                )
                );
        }

        /// <summary>
        /// 关闭程序钱停止服务器实例
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmTCPServer_FormClosing(object sender, FormClosingEventArgs e)
        {
            tcpServer.Stop();
        }

        private void treeViewClientList_AfterSelect(object sender, TreeViewEventArgs e)
        {
            //
        }

        private void treeViewClientList_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                treeViewClientList.Focus();
                treeViewClientList.SelectedNode = treeViewClientList.GetNodeAt(e.X,e.Y);
            }

        }


        private void toolStripMenuSendSingle_Click(object sender, EventArgs e)
        {
            if (treeViewClientList.SelectedNode != null)
            {
                tcpServer.SendToClient(DicTreeIPEndPoint[treeViewClientList.SelectedNode], string.Format("服务端单个消息...{0}", sendInt.ToString()));
                sendInt++;
            }
        }

        private void toolStripMenuSendAll_Click(object sender, EventArgs e)
        {
            tcpServer.SendToAll("服务端全部发送消息..." + sendInt);
            sendInt++;
        }

        private void removTreeIPEndPoint(IPEndPoint ipendPoint)
        {

            if (DicTreeIPEndPoint.Count <= 0) return;
            //foreach遍历Dictionary时候不能对字典进行Remove
            TreeNode[] keys = new TreeNode[DicTreeIPEndPoint.Count];
            DicTreeIPEndPoint.Keys.CopyTo(keys,0);
            lock (obj)
            {
                foreach (TreeNode item in keys)
                {
                    if (DicTreeIPEndPoint[item] == ipendPoint)
                    {
                        DicTreeIPEndPoint.Remove(item);
                    }
                }
            }
        }

    }
}

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

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using BenXHSocket;
using System.Threading;

namespace BenXHSocketClient
{
    public partial class FrmTCPClient : Form
    {
        BXHTcpClient tcpClient;
        
        string ip = string.Empty;
        string port = string.Empty;
        private int sendInt = 0;
        public FrmTCPClient()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void btnConnServer_Click(object sender, EventArgs e)
        {
            try
            {
                this.ip = txtServerIP.Text.Trim();
                this.port = txtServerPort.Text.Trim();

                tcpClient.InitSocket(ip, int.Parse(port));
                tcpClient.Start();
                listBoxStates.Items.Add("连接成功!");
                btnConnServer.Enabled = false;

            }
            catch (Exception ex)
            {

                listBoxStates.Items.Add(string.Format("连接失败!原因:{0}", ex.Message));
                btnConnServer.Enabled = true;
            }
        }

        private void FrmTCPClient_Load(object sender, EventArgs e)
        {
            //客户端如何处理异常等信息参照服务端
         
            BXHTcpClient.pushSockets = new PushSockets(Rec);

            tcpClient = new BXHTcpClient();
            this.ip = txtServerIP.Text.Trim();
            this.port = txtServerPort.Text.Trim();
          
        }

        /// <summary>
        /// 处理推送过来的消息
        /// </summary>
        /// <param name="rec"></param>
        private void Rec(BenXHSocket.Sockets sks)
        {
            this.Invoke(new ThreadStart(delegate
            {
                if (listBoxText.Items.Count > 1000)
                {
                    listBoxText.Items.Clear();
                }
                if (sks.ex != null)
                {
                    if (sks.ClientDispose == true)
                    {
                        //由于未知原因引发异常.导致客户端下线.   比如网络故障.或服务器断开连接.
                        listBoxStates.Items.Add(string.Format("客户端下线.!"));
                    }
                    listBoxStates.Items.Add(string.Format("异常消息:{0}", sks.ex));
                }
                else if (sks.Offset == 0)
                {
                    //客户端主动下线
                    listBoxStates.Items.Add(string.Format("客户端下线.!"));
                }
                else
                {
                    byte[] buffer = new byte[sks.Offset];
                    Array.Copy(sks.RecBuffer, buffer, sks.Offset);
                    string str = Encoding.UTF8.GetString(buffer);
                    listBoxText.Items.Add(string.Format("服务端{0}发来消息:{1}", sks.Ip, str));
                }
            }));
        }

        private void btnDisConn_Click(object sender, EventArgs e)
        {
            tcpClient.Stop();
            btnConnServer.Enabled = true;
        }

        private void btnSendData_Click(object sender, EventArgs e)
        {
            tcpClient.SendData("客户端消息!" + sendInt);
            sendInt++;
            
        }

        private void btnConnTest_Click(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(o =>
            {
                for (int i = 0; i < 100; i++)
                {
                    BenXHSocket.BXHTcpClient clientx= new  BenXHSocket.BXHTcpClient();//初始化类库  
                    clientx.InitSocket(ip, int.Parse(port));
                    clientx.Start();
                }
                MessageBox.Show("完成.!");
            });
        }


    }
}

运行程序下载:

BenXHSocket程序下载 

内容:

BenXHSocket.dll      主要程序动态库

BenXHSocketClient.exe   客户端应用程序

BenXHSocketTcpServer.exe  服务端应用程序

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

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

 

猜你喜欢

转载自blog.csdn.net/coderjyf/article/details/70255309