C# TcpListener的编程要点

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

找时间在项目中应用后,再总结一下。

原文地址:https://www.cnblogs.com/yao2yao4/p/3139341.html