1. 程式人生 > >C#網路程式設計TCP通訊例項程式簡單設計

C#網路程式設計TCP通訊例項程式簡單設計

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);
                    }
                }
            }
        }

    }
}