using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using YQ.BLL; using YQ.Commons; using YQ.Models; using System.Configuration; namespace WindowsFormsApplication1 { public partial class FormMain : Form { private Socket ServerSocket = null;//服務端 public Dictionary<string, MySession> dic_ClientSocket = new Dictionary<string, MySession>();//tcp客戶端字典 private Dictionary<string, Thread> dic_ClientThread = new Dictionary<string, Thread>();//線程字典,每新增一個鏈接就添加一條線程 private bool Flag_Listen = true;//監聽客戶端鏈接的標誌 public FormMain() { InitializeComponent(); //System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//設置該屬性 爲false } private void Form1_Load(object sender, EventArgs e) { try { //this.txtPort.Text = "6666"; //this.txtSend.Text = "服務端發送"; } catch { } } private void btnStart_Click(object sender, EventArgs e) { try { if (this.btnStart.Text == "啓動服務") { this.btnStart.Text = "中止服務"; OpenServer(Int32.Parse(this.txtPort.Text.Trim())); } else { this.btnStart.Text = "啓動服務"; CloseServer(); } } catch (Exception ex) { CloseServer(); } } private void btnSend_Click(object sender, EventArgs e) { try { if (dic_ClientSocket.Count <= 0) { this.lblState.Text = "沒有客戶端鏈接"; } else { foreach (var item in dic_ClientSocket) { string sendMessage = this.txtSend.Text.Trim(); byte[] message = System.Text.Encoding.UTF8.GetBytes(sendMessage); SendData(item.Key, message); } this.lblState.Text = "已發送客戶端"; } } catch { } } /// <summary> /// 啓動服務 /// </summary> /// <param name="port">端口號</param> public bool OpenServer(int port) { try { Flag_Listen = true; // 建立負責監聽的套接字,注意其中的參數; ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 建立包含ip和端口號的網絡節點對象; IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, port); try { // 將負責監聽的套接字綁定到惟一的ip和端口上; ServerSocket.Bind(endPoint); } catch { return false; } // 設置監聽隊列的長度; ServerSocket.Listen(100); // 建立負責監聽的線程; Thread Thread_ServerListen = new Thread(ListenConnecting); Thread_ServerListen.IsBackground = true; Thread_ServerListen.Start(); return true; } catch { return false; } } /// <summary> /// 關閉服務 /// </summary> public void CloseServer() { lock (dic_ClientSocket) { foreach (var item in dic_ClientSocket) { item.Value.Close();//關閉每個鏈接 } dic_ClientSocket.Clear();//清除字典 } lock (dic_ClientThread) { foreach (var item in dic_ClientThread) { item.Value.Abort();//中止線程 } dic_ClientThread.Clear(); } Flag_Listen = false; //ServerSocket.Shutdown(SocketShutdown.Both);//服務端不能主動關閉鏈接,須要把監聽到的鏈接逐個關閉 if (ServerSocket != null) ServerSocket.Close(); } /// <summary> /// 監聽客戶端請求的方法; /// </summary> private void ListenConnecting() { while (Flag_Listen) // 持續不斷的監聽客戶端的鏈接請求; { try { Socket sokConnection = ServerSocket.Accept(); // 一旦監聽到一個客戶端的請求,就返回一個與該客戶端通訊的 套接字; // 將與客戶端鏈接的 套接字 對象添加到集合中; string str_EndPoint = sokConnection.RemoteEndPoint.ToString(); MySession myTcpClient = new MySession() { TcpSocket = sokConnection }; //建立線程接收數據 Thread th_ReceiveData = new Thread(ReceiveData); th_ReceiveData.IsBackground = true; th_ReceiveData.Start(myTcpClient); //把線程及客戶鏈接加入字典 dic_ClientThread.Add(str_EndPoint, th_ReceiveData); dic_ClientSocket.Add(str_EndPoint, myTcpClient); } catch { } Thread.Sleep(200); } } /// <summary> /// 接收數據 /// </summary> /// <param name="sokConnectionparn"></param> private void ReceiveData(object sokConnectionparn) { MySession tcpClient = sokConnectionparn as MySession; Socket socketClient = tcpClient.TcpSocket; bool Flag_Receive = true; while (Flag_Receive) { try { // 定義一個2M的緩存區; byte[] arrMsgRec = new byte[1024 * 1024 * 2]; // 將接受到的數據存入到輸入 arrMsgRec中; int length = -1; try { length = socketClient.Receive(arrMsgRec); // 接收數據,並返回數據的長度; if (length != -1) { #region 處理接收數據 string receiveMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, length); //this.txtReceive.Text = "客戶端" + socketClient.RemoteEndPoint.ToString() // + "\r\n" + "接收" + receiveMsg; //this.txtReceive.SelectionLength = txtReceive.Text.Length; //this.txtReceive.ScrollToCaret(); //入庫操做代碼 #endregion } } catch(Exception ex) { Flag_Receive = false; // 從通訊線程集合中刪除被中斷鏈接的通訊線程對象; string keystr = socketClient.RemoteEndPoint.ToString(); dic_ClientSocket.Remove(keystr);//刪除客戶端字典中該socket dic_ClientThread[keystr].Abort();//關閉線程 dic_ClientThread.Remove(keystr);//刪除字典中該線程 tcpClient = null; socketClient = null; break; } byte[] buf = new byte[length]; Array.Copy(arrMsgRec, buf, length); lock (tcpClient.m_Buffer) { tcpClient.AddQueue(buf); } } catch { } Thread.Sleep(100); } } /// <summary> /// 發送數據給指定的客戶端 /// </summary> /// <param name="_endPoint">客戶端套接字</param> /// <param name="_buf">發送的數組</param> /// <returns></returns> public bool SendData(string _endPoint, byte[] _buf) { MySession myT = new MySession(); if (dic_ClientSocket.TryGetValue(_endPoint, out myT)) { myT.Send(_buf); return true; } else { return false; } } } /// <summary> /// 會話端 /// </summary> public class MySession { public Socket TcpSocket;//socket對象 public List<byte> m_Buffer = new List<byte>();//數據緩存區 public MySession() { } /// <summary> /// 發送數據 /// </summary> /// <param name="buf"></param> public void Send(byte[] buf) { if (buf != null) { TcpSocket.Send(buf); } } /// <summary> /// 獲取鏈接的ip /// </summary> /// <returns></returns> public string GetIp() { IPEndPoint clientipe = (IPEndPoint)TcpSocket.RemoteEndPoint; string _ip = clientipe.Address.ToString(); return _ip; } /// <summary> /// 關閉鏈接 /// </summary> public void Close() { TcpSocket.Shutdown(SocketShutdown.Both); } /// <summary> /// 提取正確數據包 /// </summary> public byte[] GetBuffer(int startIndex, int size) { byte[] buf = new byte[size]; m_Buffer.CopyTo(startIndex, buf, 0, size); m_Buffer.RemoveRange(0, startIndex + size); return buf; } /// <summary> /// 添加隊列數據 /// </summary> /// <param name="buffer"></param> public void AddQueue(byte[] buffer) { m_Buffer.AddRange(buffer); } /// <summary> /// 清除緩存 /// </summary> public void ClearQueue() { m_Buffer.Clear(); } } }