从插座读取时

时间:2012-01-16 02:20:29

标签: c# sockets tcpclient

有时从TcpClient class读取套接字时,流不会立即解释数据。例如,如果我连接到IRC服务器并且我想解释通道中的文本以识别命令。如果某人键入命令,!time!time是一个有效的函数,它会将当前时间写回服务器。

问题是如果有人以高速率发送相同的命令!time,则套接字将被淹没。如果其他人试图执行!time,则在while()循环完成读取泛洪套接字流之前,它不会写回服务器。如果用户不断发送垃圾邮件/泛滥命令,则可能需要几分钟。

static void Connect(String hostname, int port)
        {
            try
            {
                socket = new TcpClient(hostname, port);
                socket.ReceiveBufferSize = 4096;
                Console.WriteLine("Successfully connected to " + hostname);
                NetworkStream stream = socket.GetStream();
                reader = new StreamReader(stream);
                writer = new StreamWriter(stream);
                write("USER " + username + " 8 * :" + description, writer);
                write("NICK " + username, writer);
                write("NS IDENTIFY " + password, writer);//Authenticate account
                read(reader);//read the stream
                reader.Close();
                writer.Close();
                stream.Close();
                socket.Close();
            }
            catch
            {
                Console.WriteLine("Failed to connect to " + hostname);
            }
        }

下面的read()函数:

static void read(StreamReader reader)
        {
            try
            {
                while (true)
                {
                    interpret(reader.ReadLine());
                }
            }
            catch
            {
                Console.WriteLine("Unable to read from server");
            }
        }

如果要被洪水淹没,我该怎么办?因此,如果某人确实使用!time填充了该流,则不会阻止其他用户也看到他们输入!time的时间。

谢谢。

1 个答案:

答案 0 :(得分:1)

Chatbot解决方案

您必须至少处理所有传入文本以分隔消息,并确定用户发送每条消息的内容。然后,您可以按用户将它们拆分为单独的队列。您可以循环处理队列,也可以随机处理队列。或者,您可以实现令牌桶方案,其中每个 n 秒为所有用户提供一定数量的令牌,并且每个命令都使用令牌。不允许用户超过一定数量的令牌( p 秒),他们被允许囤积这些令牌。如果在命令到达时没有该用户的令牌,请将其丢弃或排队,以便下次发出令牌。


服务器端解决方案

其他用户有自己的套接字,不是吗?

一个套接字上的积压不会阻止您阅读其他套接字。你只需要编写应用程序逻辑,这样它就不会被一个人读取,它会循环播放,只有在每个人都有机会之后才从第一个读取更多内容。

通常,您使用selectWaitAny之类的函数生成就绪套接字列表。不要总是从列表中的第一个套接字读取,选择最接近你读取的最后一个套接字,或者随机选择一个。