2个线程处理具有奇怪行为的套接字

时间:2016-04-05 19:30:01

标签: c# .net sockets synchronous

我刚刚完成了包含2个套接字的C#代理(一个客户端套接字从某个客户端接收数据,一个服务器套接字从某个服务器接收数据)。

- 方法I)

以前的早期alpha版本的完全正常接收/发送程序使用以下内存吃,快速和脏的方法我将不会再次实施:

            while (true)
            {
                if (ClientSocket.Available > 0)
                {
                    // Received data from the game client
                    byte[] buf = new byte[ClientSocket.Available];
                    ClientSocket.Receive(buf);
                    Packet p = new Packet(buf);
                    Logger.Log(p.ID, LogType.PACKET);
                    // Forward re-encrypted data back to the official server
                    ServerSocket.Send(p.Encrypt());
                }

                if (ServerSocket.Available > 0)
                {
                    // Received Data from the official server
                    byte[] buf = new byte[ServerSocket.Available];
                    ServerSocket.Receive(buf);
                    Packet p = new Packet(buf);
                    Logger.Log(p.ID, LogType.PACKET);
                    // Forward re-encrypted data back to the game client
                    ClientSocket.Send(p.Encrypt());
                }
            }

- 方法II)

实际版本中的不工作接收/发送过程使用以下内存友好方法拆分为2个线程:

class ClientReceiveThread
{
    public Thread T { get; set; }
    public ClientReceiveThread(Socket ClientSocket, Socket ServerSocket)
    {
        T = new Thread(() =>
        {
            try
            {               
                while (ClientSocket.Available > 0)
                {
                    // Received data from the game client
                    byte[] buf = new byte[ClientSocket.Available];
                    ClientSocket.Receive(buf);
                    Packet p = new Packet(buf);
                    Logger.Log(p.ID, LogType.PACKET);
                    // Forward re-encrypted data back to the official server
                    ServerSocket.Send(p.Encrypt());
                }
            }
            catch (Exception e)
            {
                ExceptionHandler.Handle(e);
            }
        });
        T.Start();
    }
}

class ServerReceiveThread
{
    public Thread T { get; set; }
    public ServerReceiveThread(Socket ClientSocket, Socket ServerSocket)
    {
        T = new Thread(() =>
        {
            try
            {
                while (ServerSocket.Available > 0)
                {
                    // Received Data from the official server
                    byte[] buf = new byte[ServerSocket.Available];
                    ServerSocket.Receive(buf);
                    Packet p = new Packet(buf);
                    Logger.Log(p.ID, LogType.PACKET);
                    // Forward re-encrypted data back to the game client
                    ClientSocket.Send(p.Encrypt());
                }
            }
            catch (Exception e)
            {
                ExceptionHandler.Handle(e);
            }
        });
        T.Start();
    }
}

方法I)在客户端和服务器端口接收数据的情况下工作,而方法II)仅接收来自ClientReceiveThread的数据。 为什么方法II中的ServerReceiveThread不能接收数据?它基本上与while(true)循环中的代码相同,只移植到单独的线程。

任何建议或答案都非常感谢。 提前谢谢!

1 个答案:

答案 0 :(得分:1)

通过避免"可用"修复它。属性:

class ClientReceiveThread
{
    public Thread T { get; set; }
    public ClientReceiveThread(Socket ClientSocket, Socket ServerSocket)
    {
        T = new Thread(() =>
        {
            try
            {               
                byte[] buf = new byte[1024];
                while (ClientSocket.Receive(buf) > 0)
                {
                    // Received data from the game client
                    Packet p = new Packet(buf);
                    Logger.Log(p.ID, LogType.PACKET);
                    // Forward re-encrypted data back to the official server
                    ServerSocket.Send(p.Encrypt());
                }
            }
            catch (Exception e)
            {
                ExceptionHandler.Handle(e);
            }
        });
        T.Start();
    }
}

class ServerReceiveThread
{
    public Thread T { get; set; }
    public ServerReceiveThread(Socket ClientSocket, Socket ServerSocket)
    {
        T = new Thread(() =>
        {
            try
            {
                byte[] buf = new byte[1024];
                while (ServerSocket.Receive(buf) > 0)
                {
                    // Received Data from the official server
                    Packet p = new Packet(buf);
                    Logger.Log(p.ID, LogType.PACKET);
                    // Forward re-encrypted data back to the game client
                    ClientSocket.Send(p.Encrypt());
                }
            }
            catch (Exception e)
            {
                ExceptionHandler.Handle(e);
            }
        });
        T.Start();
    }
}