C#网络编程之TCP(四)

一、并发的访问

  什么是并发的访问呢?并发访问是指多个客户端同时连接到服务器。前几节的服务器代码,支持并发访问吗?

while (true)
{
    // 监听客户端发起连接
    Socket conn = socket.Accept();

    // 处理此连接的请求(可能要较长的时间!// 关闭此连接
    conn.Close();
}

  显然,第一个客户端被处理的过程中,第二个客户端是连接不上来的。

  那怎么解决这个问题呢?我们可以采用多线程的模式来实现并发的访问。

while (true)
{
    // 监听客户端发起连接
    Socket conn = socket.Accept();

    // 创建一个线程,在线程里来处理这个连接

    // 关闭此连接
}

 二、多线程模式

  当有客户端连接上来时,创建一个线程来处理这个连接的所有请求。

static void Main(string[] args)
{
    const string ip = "127.0.0.1";
    const int port = 10002;

    // 建立服务器
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    EndPoint point = new IPEndPoint(IPAddress.Parse(ip), port);
    socket.Bind(point);
    socket.Listen(100);

    while (true)
    {
        // 监听客户端发起连接
        Socket conn = socket.Accept();

        ServiceHandler serviceHandler = new ServiceHandler(conn);

        // 创建一个线程处理
        Task.Run(serviceHandler.Run);

    }

}
public class ServiceHandler
{
    Socket conn;
    public ServiceHandler(Socket conn)
    {
        this.conn = conn;
    }

    public void Run()
    {
        try
        {


            // 接收数据
            byte[] bytes = new byte[4];
            // 先获取内容长度
            conn.Receive(bytes);
            int inputLength1 = BitConverter.ToInt32(bytes, 0);
            byte[] msgBytes1 = new byte[inputLength1];
            // 再获取内容
            conn.Receive(msgBytes1);
            string inputMsg1 = Encoding.UTF8.GetString(msgBytes1, 0, inputLength1);
            Console.WriteLine("<<: " + inputMsg1);


            // 发送数据
            string outputMsg1 = "Hello World!";
            byte[] buf = new byte[4];
            // 先发送内容的长度
            ConvertIntToByteArray(Encoding.UTF8.GetBytes(outputMsg1).Length, ref buf);
            conn.Send(buf);
            // 再发送内容
            conn.Send(Encoding.UTF8.GetBytes(outputMsg1));
        }
        catch (Exception ex)
        {

            throw ex;
        }

        conn.Close();
    }

    private bool ConvertIntToByteArray(int m, ref byte[] arry)
    {
        if (arry == null) return false;
        if (arry.Length < 4) return false;

        arry[0] = (byte)(m & 0xFF);
        arry[1] = (byte)((m & 0xFF00) >> 8);
        arry[2] = (byte)((m & 0xFF0000) >> 16);
        arry[3] = (byte)((m >> 24) & 0xFF);

        return true;
    }
}

 

三、非托管资源(网络连接句柄)的关闭

  每一个客户端连接到服务器时都会创建一个socket连接。如果一个客户端连上服务器,什么消息也不发,那么服务器就需要将这些连接给关闭掉。所以必须要添加连接设置,在超时之后自动关闭连接

public class ServiceHandler
{
    Socket conn;
    public ServiceHandler(Socket conn)
    {
        this.conn = conn;
    }

    public void Run()
    {
        try
        {
            // 设置超时时间
            conn.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 10 * 1000);
            conn.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 10 * 1000);

            // 接收数据
            byte[] bytes = new byte[4];
            // 先获取内容长度
            conn.Receive(bytes);
            int inputLength1 = BitConverter.ToInt32(bytes, 0);
            byte[] msgBytes1 = new byte[inputLength1];
            // 再获取内容
            conn.Receive(msgBytes1);
            string inputMsg1 = Encoding.UTF8.GetString(msgBytes1, 0, inputLength1);
            Console.WriteLine("<<: " + inputMsg1);


            // 发送数据
            string outputMsg1 = "Hello World!";
            byte[] buf = new byte[4];
            // 先发送内容的长度
            ConvertIntToByteArray(Encoding.UTF8.GetBytes(outputMsg1).Length, ref buf);
            conn.Send(buf);
            // 再发送内容
            conn.Send(Encoding.UTF8.GetBytes(outputMsg1));
        }
        catch (Exception ex)
        {

            throw ex;
        }

        conn.Close();
    }

    private bool ConvertIntToByteArray(int m, ref byte[] arry)
    {
        if (arry == null) return false;
        if (arry.Length < 4) return false;

        arry[0] = (byte)(m & 0xFF);
        arry[1] = (byte)((m & 0xFF00) >> 8);
        arry[2] = (byte)((m & 0xFF0000) >> 16);
        arry[3] = (byte)((m >> 24) & 0xFF);

        return true;
    }
}

 

posted @ 2022-09-15 10:44  Zeng。  阅读(327)  评论(0编辑  收藏  举报