C#網路程式設計TCP通訊例項程式簡單設計
阿新 • • 發佈:2019-01-25
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); } } } } } }