Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 网络流在发送多条Protobuf消息时关闭_C#_.net_Protobuf Net_Networkstream - Fatal编程技术网

C# 网络流在发送多条Protobuf消息时关闭

C# 网络流在发送多条Protobuf消息时关闭,c#,.net,protobuf-net,networkstream,C#,.net,Protobuf Net,Networkstream,我使用protobuf net和.net的TCPClient&NetworkStream在一台服务器和多个客户端之间进行通信。对于发送消息,我在两侧使用以下方法: public static bool WriteProtocolBufferToStream(System.IO.Stream stream, object protoBufObject) { // ... check parameters ...

我使用protobuf net和.net的TCPClient&NetworkStream在一台服务器和多个客户端之间进行通信。对于发送消息,我在两侧使用以下方法:

   public static bool WriteProtocolBufferToStream(System.IO.Stream stream, object protoBufObject)
    {            
            // ... check parameters ...                
            // ... Determine the 'fieldNumber' of the 'protoBufObject' via a helper dictionary ...  
            if (fieldNumber > -1)
            {
                try { Serializer.NonGeneric.SerializeWithLengthPrefix(stream, protoBufObject, ProtoBuf.PrefixStyle.Base128, fieldNumber); }
                catch (Exception ex)
                {
                    Logger.Instance.Error("Exception: " + ex.Message);
                    return false;
                }
            }
            else
            {
                Logger.Instance.Error("unknown message type");
                return false;
            }
            return true;            
    }
在只有一些客户端和很少消息的小场景中,一切都很好。但我在大约40个客户端和许多交换消息的场景中遇到了问题。消息非常小(包含1到5个小字符串),但服务器可能同时发送多条(最多200条)这些消息

在一段时间(几分钟到几个小时)后引发以下异常:

源代码是protobuf net的类构造函数。它引发此异常,因为
NetworkStream
dest的
CanWrite
属性为false。我的问题是:
CanWrite
为什么在一段时间后从true变为false?这可能与缓冲区溢出有关(因为我同时发送许多消息)?我怎样才能修好它

编辑:

正如[Marc Gravell]已经指出的那样,
NetworkStream
被处理,因此
CanWrite
从true变为false。例如,如果我尝试访问流对象的
WriteTimeout
属性,我会得到以下结果:

System.ObjectDisposedException:无法访问已处置的对象。
对象名称:“System.Net.Sockets.Socket”。
位于System.Net.Sockets.Socket.GetSocketOption(SocketOptionLevel选项级别,SocketOptionName选项名称)
在System.Net.Sockets.NetworkStream.get_WriteTimeout()中
在Utilities.CommunicationHelper.WriteProtocolBufferToStream(网络流,对象ProtoBufoObject)
...

我仍然在我的代码中寻找一些东西,这可能会导致套接字的处理。还有什么原因会导致套接字在一段时间(几个小时)后被释放?

也许您正在耗尽服务器的TCP/IP端口

您没有提到您的服务器正在运行哪个操作系统,但假设它是2008年的服务器,那么您有16000个可用端口(49152-65535)。关闭连接时,端口将在再次可用之前保持4分钟的TIME_WAIT状态。这意味着,如果您在不到4分钟的时间内连接超过16000个,您的服务器将开始拒绝连接

遇到错误时,请尝试在服务器上运行以下命令:

netstat -p TCP -ano > netstat.txt
netstat.txt中的行数告诉您处于已建立或time_wait状态的TCPv4连接数

你可以调整这个。通过增加动态端口的数量、缩短等待时间间隔或两者兼而有之

要查看实际值,请执行以下操作:

  • Time_wait(TcpTimedWaitDelay)(默认值为240,如果找不到该值,则为4分钟)

  • 动态端口范围:

    netsh int ipv4 show dynamicportrange tcp
    
一些有用的资源:


对于
网络流
,一点IL分析表明
可以写
遵从
可写
。反过来,
m_Writeable
以三种方式变为
false

  • 当它被处理时
  • 当使用
    access
    参数作为
    FileAccess.Read创建时
  • 可写
    属性(
    受保护
    )被分配时(注意,我看不到框架中实际使用此属性的证据)

所以:如果你说这种情况发生在一个已经建立的
网络流上,并且已经好了一段时间了,那么最有可能的答案是它在某个时候被处理掉了,可能是因为关闭了谢谢你的回答。因此,现在我必须找出NetworkStream被关闭/处置的原因。我添加了更多的日志输出,以便在新的测试运行中对此进行调查。protobuf net Dispose()是否关闭()使用NetworkStream的StreamReader或StreamWriter?根据,这将处理使用过的网络流。@Rob iirc流读写器确实关闭了底层流。从内存中看,protobuf net没有-但我必须检查以确保
网络流的
套接字
确实已被释放-请参见问题中的编辑。您是否查看了protobuf net中StreamReader/StreamWriter的使用情况?protobuf网络可能是导致处理的原因吗?谢谢你的回答,但它似乎与端口耗尽无关。我的机器是一台2008服务器,16384个端口中只有大约50个正在使用。我看不到端口耗尽的迹象。似乎没有任何东西指向这一点。这一信息当然没有。这不仅仅是猜测,根本不可能是原因。你没有提到它,但你在使用线程吗?只是猜测一下,因为您提供的信息有点稀疏:-)@Dag:是的,我使用线程。在当前版本中,I
lock()
方法中的所有内容。问题仍然存在。因此,这不应该是线程问题。@usr套接字的创建和处理未显示,并且在创建过程中可能会泄漏/错误处理,当通信量增加时似乎会发生错误(尽管确切的容量未知)。根据最初的问题,如何消除端口耗尽这一可能的原因?
reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\TcpTimedWaitDelay
netsh int ipv4 show dynamicportrange tcp