通信程序截图:
压力测试服务端截图:
俩个客户端链接服务端测试截图:
服务端:
客户端
运行动态图
C#程序设计代码
BenXHSocket.dll主要代码设计
SocketObject类
[csharp] view plain copy
- /*****************************************************
- * 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类
[csharp] view plain copy
- /*****************************************************
- * 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类[csharp] view plain copy
- /*****************************************************
- * 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服务端监听类
[csharp] view plain copy
- /*****************************************************
- * 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客户端类
[csharp] view plain copy
- /*****************************************************
- * 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
- }
- }
- }
服务端和客户端窗体应用程序主要方法设计实现
服务端窗体应用程序主要方法代码:
[csharp] view plain copy
- 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);
- }
- }
- }
- }
- }
- }
客户端窗体应用程序主要代码
[csharp] view plain copy
- 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