C# 如何重新使用TCP客户端?

C# 如何重新使用TCP客户端?,c#,tcp,tcpclient,system.net.sockets,C#,Tcp,Tcpclient,System.net.sockets,我在System.Net.WebRequest和System.Net.HttpRequest与多线程和套接字使用的兼容性方面遇到了问题。我试图降低级别,推出自己的简单Http类 由于以前的问题是每个线程创建的套接字太多太快,所以我尝试在多次迭代(for循环)中使用单个套接字(每个线程1个) 代码: 我的测试类(具有硬编码的ip和端口,直到我可以使其工作): 静态空隙干管: using( Foo foo = new Foo() ) { for( int i = 0; i < 10;

我在System.Net.WebRequest和System.Net.HttpRequest与多线程和套接字使用的兼容性方面遇到了问题。我试图降低级别,推出自己的简单Http类

由于以前的问题是每个线程创建的套接字太多太快,所以我尝试在多次迭代(for循环)中使用单个套接字(每个线程1个)

代码:

我的测试类(具有硬编码的ip和端口,直到我可以使其工作):

静态空隙干管:

using( Foo foo = new Foo() ) {
    for( int i = 0; i < 10; i++ ) {
        foo.Execute();
    }
}
使用(Foo-Foo=new-Foo()){
对于(int i=0;i<10;i++){
foo.Execute();
}
}
错误

我收到的错误是
不允许在未连接的套接字上执行该操作。
在for循环的第一次迭代成功完成后

我理解错误的原因(读取响应后,
TcpClient.Client
关闭),但我不知道如何明确地告诉套接字保持打开状态

编辑 进一步检查从服务器返回的HTTP响应,其中包含
连接:Close
。我假设,因为这是原始TCP,所以它不会解析HTTP。这可能是问题的根源吗?(如果是的话,有没有办法忽略它)

更改main方法中的顺序,这样每次迭代都会创建一个新对象

for( int i = 0; i < 10; i++ ) 
{
    using( Foo foo = new Foo() ) 
    {
        foo.Execute();
    }
}
下面是用法

using( Foo foo = new Foo() ) {
    foo.Open();
    for( int i = 0; i < 10; i++ ) {
        foo.Execute();
    }
    foo.Close();
}
使用(Foo-Foo=new-Foo()){
foo.Open();
对于(int i=0;i<10;i++){
foo.Execute();
}
foo.Close();
}

我认为您的KeepAlive实现不太正常。关闭流时,您正在关闭底层套接字。将流创建移动到构造函数

public Foo() 
{
    m_tcpClient = new TcpClient( m_ip, m_port );
    m_tcpStream = m_tcpClient.GetStream();
}
然后使两个对象都保持活动状态,直到整个对象关闭:

    void IDisposable.Dispose() 
    {
        m_tcpStream.Close();
        m_tcpClient.Client.Dispose();
    }

调用第一个
Execute
时,
using
关闭(处置)
m_tcpClient
。使用s,您不需要这些

using( var stream = m_tcpClient.GetStream() )

我读到一个问题,他不想创建多个实例。虽然这将在同步程序中运行,但当我尝试在多线程环境中使用它时,它对套接字使用没有帮助。(操作系统清理套接字与线程迭代不匹配,因此单个线程将创建多个套接字,从而快速消耗资源)
Dispose
如果要这样做,可能应该调用
Close
。不过,我不认为有什么令人信服的理由不将
Close
重命名为
Dispose
。与
Open
对称,可能…但是
Close
实际上只是处理,所以…@cHao是的,我同意,但这只是对OP的一个提示,我试图表明在每个for步骤之后不应该处理连接。还有一些块代码丢失,以及异常处理和参数验证等。这导致错误
流不可写
System.IO异常,根本原因是TcpClient仍在关闭我想知道它是否期望一个特定的事件序列,以便使连接可读写?编辑:是否有理由必须实现iDisposable?为什么不试着去掉它,看看它的行为是否更符合预期?
    void IDisposable.Dispose() 
    {
        m_tcpStream.Close();
        m_tcpClient.Client.Dispose();
    }
using( var stream = m_tcpClient.GetStream() )