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

Unity 简单TCP通信实现 参考教程:【01_C#入门到精通】新手强烈推荐:C#开发课程,一整套课程_哔哩哔哩_bilibiliP178-P187 测试结果: 测试方法: 连接失败可能原因: 检查是否关闭防火墙;是否关闭外网vpn;ip地址是否正确;两台机子要连同一局域网 ... 阅读详情

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程序下载 

源代码工程文件下载

开源地址下载https://gitee.com/JiYF/BXHSocket

内容:

BenXHSocket.dll      主要程序动态库

BenXHSocketClient.exe   客户端应用程序

BenXHSocketTcpServer.exe  服务端应用程序

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

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

 

C#网络编程实战:TCP与UDP通信及串口通信 网络协议是用于计算机网络中进行数据交换的一套规则和标准。它定义了数据的格式、传输方式以及处理过程,确保了网络中的设备能够顺畅、正确地交换信息。在众多网络协议中,传输控制协议(TCP)和用户数据报协议(UDP)是应用最为广泛的两种,分别适用于不同类型的网络通信需求。 阅读详情

相关推荐

C#网络编程:TCP/IP通信客户端实现

C#是一种优雅、类型安全的面向对象语言,它集成并发展了C和C++的优点。C#由微软开发,旨在为.NET框架创建强大的应用程序。其特点包括易用性、安全性、平台独立性、组件化和集成的开发环境等。C#语言允许开发者创建从简单的桌面应用程序到复杂的分布式Web服务的广泛应用程序。网络编程方面,C#提供了强大的类库和API,使得开发者可以方便地进行各种网络操作。

weixin_30674431的博客 1184

C#网络应用编程——复习总结

C#网络应用编程总结笔记 HENU网络工程专业C#网络应用编程专业课

weixin_52357218的博客 7746

基于C# Winform完成Tcp客户端与服务端、udp客户端服务端通讯工具

C#基于TCP协议的服务器端和客户端通信编程的基础教程,简单实现通讯。代码简单明了。

C#网络应用编程

通过本实验,熟悉和掌握Lambda表达式、Action委托和Func 委托的使用。

qq_59035907的博客 1047

C#Winform使用TCPListener加多线程编程实现客户端服务器端聊天模式

C#Winform使用TCPListener和TCPClient加多线程编程实现客户端服务器端聊天模式,使用委托避免控件访问异常

基于C# 的TcpClient/TcpListener的一对多的网络通信程序源码

winform使用TcpClient/TcpListener类结合网络流建立多个客户机连接服务器程序,实现网络聊天通信的软件。程序比较完整,可以直接使用。

C#语言基础问题20:如何利用C#进行网络编程?

如何利用C#进行网络编程?

lainiao110的专栏 793

2026软件测试面试题全解析:从用例设计到接口自动化与性能实战

在软件测试岗位的招聘考察中,面试官越来越看重候选人解决实际问题的工程能力,而不仅仅是背诵概念。从最基础的测试用例设计出发,覆盖功能测试、接口测试、自动化测试、性能测试、数据库与Redis一致性等核心知识体系,是应对中高级岗位面试的关键路径。理解Postman抓包、Python脚本、Pytest框架、JMeter压测指标背后的原理,能帮助测试人员构建完整的质量保障思维。当AI辅助测试成为行业新趋势时,掌握数据校验链路与风险识别意识,更能体现资深测试工程师的竞争力。本文围绕2026年高频软件测试面试题,梳理了从

weixin_28676289的博客 246

C#网络编程

C#网络通信 1.网络通信的方式 1)同步方式 同步方式是指当发送方发送一个数据包以后,一直等到接收方响应后,才可以发送下一个数据包。(串行运行) 2)异步方式 异步方式是指发送方发送数据包以后,不等接收方响应,就接着发送下一个数据包。(并行运行) 3)阻塞套接字 阻塞套接字是指在执行此套接字的网络调用时,直到调用成功才返回,否则此套接字就一直阻塞在网络调用上。 4)非阻塞套接字

BerMaker 2万+

钢铁雄心4存档修改全攻略:从基础设置到高级玩法(附国家代码表)

本文详细解析《钢铁雄心4》存档修改技巧,从基础设置到高级玩法全覆盖。包括存档文件位置、格式转换、国家实力调整、国际关系修改等实用内容,并附赠国家代码表。掌握存档修改技能,解锁游戏全部潜力,实现精细参数控制,超越控制台指令的局限。

weixin_29233857的博客 1439

别再只盯着DDR5了!聊聊3D DRAM:它凭什么能解决AI算力的内存墙难题?

本文深入探讨了3D DRAM技术如何突破AI算力的内存墙限制。通过立体堆叠架构,3D DRAM在存储密度、带宽和延迟方面实现显著提升,有效解决AI训练和推理中的内存瓶颈问题。文章还分析了三星、SK海力士等巨头的技术路线图,并指出商业化面临的挑战与机遇。

weixin_42685438的博客 192

C#使用TCP进行聊天通信(详细解析)

TCP通信可以使用Socket和TcpListene进行通信,TcpListene是Socket的一个封装,可以更好的操作Socket,底层依然是socket。使用NetworkStream类,把流分别给BinaryReader读,BinaryWriter写。1.使用TcpListener实例化,得到服务器的ip和端口。两者区别不大,主要是NetworkStream类的使用。进行通信分为2部分,一个是服务端,一个是客户端。服务器收到消息后,把消息发给客户端。5.读取服务器的流,接收消息。...

故里2130 1万+

避坑指南:为什么你的conda环境装不上Mamba?从CUDA到ABI的深度排查

本文深入解析conda环境中安装Mamba架构时常见的CUDA版本冲突、ABI不匹配等问题,提供从基础检查到深度排查的系统化解决方案。针对`causal-conv1d`和`mamba-ssm`安装失败场景,详细讲解PyTorch版本绑定、编译器工具链兼容性等关键技术要点,并给出预编译wheel选择、动态链接库配置等实用修复方案。

weixin_33738555的博客 346

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

2017-12-21 15:33:14newbie_xymt阅读数 1511 采用自带TcpClient和TcpListener设计一个Tcp通信的例子 只实现了TCP通信 通信程序截图: 压力测试服务端截图: 俩个客户端链接服务端测试截图: 服务端: 客户端 运行动态图 C#程序设计代码 BenXHSocket.dll主要代码设计 SocketObje...

cxu123321的博客 1346

AI测试干货:让大语言模型稳定输出 JSON 的四种实现方案

用大语言模型做测试用例生成、数据提取时,最头疼的就是让它老老实实返回 JSON。你以为它会给你 `{"name":"张三"}`,结果它来一句"好的,这是生成结果:```json...",或者干脆在 JSON 里加注释,直接把你的 `json.loads()` 干崩溃。 模型本质上是个话痨,天生爱解释。但我们要的是结构化数据,不是聊天记录。我整理了四种实战方案,从最简单的提示词技巧到工程化框架,覆盖了从快速验证到生产环境的各种场景。

blues_C的博客 958

CMake教程:C++ CMake自定义find_package并在其它项目使用

find_package 是 CMake 中一个非常重要的命令,用于在系统中找到外部库或包,并将其包含到项目中。: 要查找的包的名称。[version]: 可选的版本号。如果指定了版本号,CMake 会尝试找到该版本或更高版本的包。[REQUIRED]: 如果指定了这个关键字,找不到包时会产生一个错误并终止配置过程。: 指定要查找的包的组件。: 指定可选的组件,即使找不到这些组件,配置过程也会继续。: 指定查找包的模式,CONFIG表示查找配置文件,MODULE表示查找模块文件。

琅嬛福地 1564

C#网络编程初步之TCP

阅读背景:本文针对有C#的初学者而写的,主要讲解如何利用C#进行网络编程。如果你已经有一些网络编程的经验(只需要懂得网络编程的基本常识即可),并且理解C#的基本语法,那么这篇文章可以很快地带你进入C#网络编程的世界。如果你的基础不好,也不要紧,我相信这篇文章也会有你需要的内容。

尘封的专栏 4714

uniapp - 详解使用高德地图在地图上实现绘制边界/点聚合/行政区域高亮等功能,Uniapp高德地图点聚合标记及绘制点线面示例代码(全端兼容H5网页、小程序、安卓app、苹果app、nvue)

uni-app,h5移动端网页,微信小程序,支付宝小程序,Android安卓,苹果ios,app,nvue,高德地图,uniAPP高德地图实现点聚合,地图区域描边、点标记、点信息详情弹窗,实现绘制边界区域,uniapp H5使用高德地图实现点聚合、行政区域高亮,实现高德地图的marker聚合功能,高德地图进行marker标点,点信息展示,点击标记点弹出对话框,点击聚合点后显示信息模态框,打标点,【Uniapp】高德地图的接入自定义标点与信息窗体使用,绘制行政区域边界,绘制多边形,电子围栏,高德行政区划边界,

✅ 精选推荐文章 1万+

C# 网络编程--关于TCP 通信(一)

• 第一次握手:客户端向服务器发送一个 SYN(同步)包,请求建立连接。• 第二次握手:服务器收到 SYN 包后,回应一个 SYN+ACK(同步确认)包,表示同意建立连接。• 第三次握手:客户端收到 SYN+ACK 包后,发送一个 ACK(确认)包,确认连接已建立。

仰望星空的人 2154

【uniapp踩坑记】App Store上传失败:Invalid Swift Support错误怎么解决?

作为一个前端出身的开发者,用 uniapp 开发原生 App 已经够挑战了,打包 iOS 上传 App Store 更是处处暗雷。这次的坑虽然小,但确实容易忽略。如果你也遇到了类似的报错,希望这篇文章能帮你少踩一次坑!

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1144

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

c# 网络编程之tcp

一、概述 UDP和TCP是网络通讯常用的两个传输协议,C#一般可以通过Socket来实现UDP和TCP通讯,由于.NET框架通过UdpClient、TcpListener 、TcpClient这几个类对Socket进行了封装,使其使用更加方便, 本文就通过这几个封装过的类讲解一下相关应用。 二、基本应用:连接、发送、接收 服务端建立侦听并等待连接: TcpListener tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 9000); t

chinaherolts2008的博客 8902

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C#网络编程:基于TCP通信协议

网络编程是指编写运行在不同设备(计算机、嵌入式设备等)上的程序,通过网络协议实现设备间的数据通信。简单来说,就是让两台 / 多台设备 “对话” 的编程方式。其核心目标是跨设备的数据传输与交互,依赖 TCP/IP 协议族等基础网络协议,TCP 是其中最常用的 “可靠传输协议”。本文的示例代码实现了最基础的 TCP 客户端 - 服务器通信:客户端发起连接并发送字符串,服务器监听连接、接收数据并返回响应。背后的核心是 TCP 协议的 “面向连接、可靠性”,通过三次握手建立连接、四次挥手断开连接,借助。

2301_77869434的博客 1399

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

上一篇: C#串口介绍以及简单串口通信程序设计实现
下一篇: 倍福TwinCAT3上位机与PLC通信测试(ADS通信) 包含C#和C++代码
JiYF
博客等级 码龄11年 356粉丝 50原创
评论 82
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值