using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Threading; using System.Windows.Forms; namespace Server { public partial class Form1 : Form { public Form1() { InitializeComponent(); listener = new TcpListener(IPAddress.Any, 9009);// 端口根據需要確定 listener.Start(); // 后台線程1:用於接收tcp連接請求,並將網絡流加入列表。隨主線程的退出而退出。 new Thread(() => { while (true) { Thread.Sleep(100);// 可以根據需要設置時間 if (!listener.Pending()) { continue; } var client = listener.AcceptTcpClient(); // 下面屬性根據需要進行設置 // client.ReceiveBufferSize // client.ReceiveTimeout // client.SendBufferSize // client.SendTimeout if (!client.Connected) { continue; } streams.Add(client.GetStream()); } }) { IsBackground = true }.Start(); // 后台線程2:用於接收請求,並作出響應。隨主線程的退出而退出。 new Thread(() => { while (true) { Thread.Sleep(100);// 可以根據需要設置時間 if (streams == null || streams.Count == 0) { continue; } streams = streams.Where(s => s.CanRead && s.CanWrite).ToList(); foreach (var stream in streams.Where(stream => stream.CanRead && stream.CanWrite)) { AsyncReceiveBytes(stream, s => { // todo:對result進行解碼 // todo:對收到指令進行邏輯判斷,得出待響應的C#對象 AsyncSendBytes(s, new byte[0]); // todo:將待響應的C#對象轉換成字節數組,替換new byte[0]。 }); } } }) { IsBackground = true }.Start(); } // 發送事件和目標的入口 public void SendEventAndTarget() { if (streams == null || streams.Count == 0) { return; } streams = streams.Where(s => s.CanRead && s.CanWrite).ToList(); foreach (var stream in streams.TakeWhile(stream => stream.CanWrite)) { AsyncSendBytes(stream, new byte[0]);// todo:這里將待發送的C#對象轉換的字節數組替換new byte[0]。 } } private static void AsyncReceiveBytes(NetworkStream stream, Action<NetworkStream> callback) { // 短時后台線程:用於處理網絡流的讀操作,處理完成后即歸還線程池。 // 每個網絡流都會分配一個線程。 //ThreadPool.SetMaxThreads();根據需要設置。 ThreadPool.QueueUserWorkItem(delegate { var buffer = new byte[1024];// 1024:根據需要進行設置。 var result = new byte[0]; do { var a = stream.Read(buffer, 0, buffer.Length); result = result.Concat(buffer.Take(a)).ToArray(); } while (stream.DataAvailable); callback(stream); }); } private static void AsyncSendBytes(NetworkStream stream, byte[] bytes) { // 短時后台線程:用於處理網絡流的寫操作,處理完成后即歸還線程池。 // 每個網絡流都會分配一個線程。 //ThreadPool.SetMaxThreads();根據需要設置。 ThreadPool.QueueUserWorkItem(delegate { try { stream.Write(bytes, 0, bytes.Count()); } catch (Exception) { MessageBox.Show("遠程主機主動斷開此連接!");// 也可以做其它處理。 } }); } private readonly TcpListener listener; // 網絡流列表 private List<NetworkStream> streams = new List<NetworkStream>(); } }
找時間在項目中應用后,再總結一下。