简体   繁体   English

在C#中扩展TcpClient类

[英]Extending TcpClient class in C#

I am writing server application and I want to do something like this: 我正在编写服务器应用程序,我想做这样的事情:

class MyClient : TcpClient
{        
    public StreamReader Reader { get; }
    public StreamWriter Writer { get; }
    public MyClient()
    {
          Reader = new StreamReader(this.GetStream());
          Writer = new StreamWriter(this.GetStream());           
    }       
}

Then I want to listen to an incoming connection and create MyClient object: 然后我想听一个传入的连接并创建MyClient对象:

TcpListener listener= new TcpListener(IPAddress.Parse(Constants.IpAddress), Constants.Port);
MyClient client = (MyClient)listener.AcceptTcpClient();

I know that I cant downcast like this ( TcpClient is not MyClient ). 我知道我不能像这样垂头丧气( TcpClient不是MyClient )。 But MyClient Is TcpClient , so what do I need to do, to accomplish such scenario? MyClientTcpClient ,那么我需要做什么才能完成这样的场景呢? create a MyClient constructor that takes TcpClient argument and invokes base TcpClient class constructor. 创建一个MyClient构造函数,该构造函数接受TcpClient参数并调用基本TcpClient类构造函数。 I want MyClient to be a TcpClient instead of having TcpClient property. 我希望MyClient成为TcpClient而不是TcpClient属性。 Or maybe Socket class will be better in my case? 或者也许Socket类在我的情况下会更好?

Doing

(MyClient)listener.AcceptTcpClient();

will never work, whatever you do, because it always return regular TcpClient (and this method is not virtual in TcpListener so you cannot change that). 无论你做什么都不会工作,因为它总是返回常规TcpClient (这个方法在TcpListener不是虚拟的,所以你不能改变它)。 Same story with AcceptSocket . AcceptSocket相同的故事。 You can create a proxy class which will not inherit from TcpClient but will implement all the same public members and proxy their implementation to real TcpClient you store in private field and pass to constructor. 您可以创建一个代理类,该代理类不会从TcpClient继承,但会实现所有相同的公共成员,并将其实现代理到您存储在私有字段中的实际TcpClient并传递给构造函数。 However then you cannot pass that class to any method that expects regular TcpClient . 但是,您无法将该类传递给任何需要常规TcpClient

Implementation of AcceptTcpClient creates TcpClient using constructor which accepts socket, however this constructor is internal so you cannot use this way. AcceptTcpClient TcpClient使用接受套接字的构造函数创建TcpClient ,但是这个构造函数是内部的,因此您不能使用这种方式。

Another option that comes to mind is: 想到的另一个选择是:

class MyClient : TcpClient
{
    public StreamReader Reader { get; }
    public StreamWriter Writer { get; }
    public MyClient(Socket acceptedSocket)
    {
        this.Client.Dispose();
        this.Client = acceptedSocket;
        this.Active = true;
        Reader = new StreamReader(this.GetStream());
        Writer = new StreamWriter(this.GetStream());
    }
}

And then pass socket from AcceptSocket to constructor. 然后将套接字从AcceptSocket传递给构造函数。 But I don't like it, because default constructor of TcpClient will be called, which creates new socket (which is disposed at the first line of constructor above). 但我不喜欢它,因为将调用TcpClient默认构造函数, TcpClient会创建新的套接字(它位于上面构造函数的第一行)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM