Implement an.Net socket based on event notifications

  • 2020-05-05 11:07:49
  • OfStack

    MFC past, I used it in two classes of packaging Winsock CSocket and CAsyncSocket, I always thought it which the event notification function is good, especially in the connection of the two sides to send and receive data is useful when no certain rules, although not the event notification can also function of it, but you need to loop check the state of the socket or block waiting for, if these trivial work to do every time is very troublesome, so I just want to make a packaging on these functions. Of course, delegate and event are the best choices in.net. Here are some of the details of my implementation:

    first to talk about the idea: in fact, this is still very simple, estimated that the masters will be dismissive of ^_^. When the socket starts to work, such as start to listen, the beginning of the connection, start a thread continuously detect the state of the socket, when an event state condition is met to trigger this event, to know the specific detection of the socket state method, please see below.

    usual socket programming may need to use the function is: connect the success or failure of the notification, in the listening socket have notice of the pending connections, data can be received notice, the socket is closed, there is a socket can be free to send data to inform, I has made to the above several function encapsulation, but I think the most behind a function useful???????

    I Socket class from System Net. Sockets. Socket inherited, the name of the class TcpEventSocket, implementation is as follows:

    first declares the delegate type of the event, depending on the code

    public delegate void AcceptConnectionHandler();

    public delegate void ConnectCompletedHandler(bool connected); //connected indicates whether the connection was successful or not
    public delegate void DataCanSendHandler();

    public delegate void DataCanReceiveHandler(int buffersize); // current acceptable amount of data

    public delegate void SocketClosedHandler();

What does     actually mean, and what does
mean
    public event AcceptConnectionHandler AcceptConnection;

    public event ConnectCompletedHandler ConnectCompleted;

    public event DataCanSendHandler DataCanSend;

    public event DataCanReceiveHandler DataCanReceive;

    public event SocketClosedHandler SocketClosed;

    adds several additional virtual methods that are used to trigger the event

    protected virtual void OnAcceptConnection();
    protected virtual void OnConnectCompleted(bool connected)

    protected virtual void OnDataCanSend()
    protected virtual void OnDataCanReceive(int buffersize)

    protected virtual void OnSocketClosed()

    in order to start the detection thread at the appropriate machine, I rewrote the methods of several base classes:

    new public void Listen(int backlog)

    {

    base.Listen(backlog);

    sockState = SocketState.Listenning;

    if (!checkThread.IsAlive)

    checkThread.Start();

    }

    new public void Connect(EndPoint remoteEP)

    {

    try

    {

    base.Connect(remoteEP);

    this.Blocking = false; // set the non-blocking state for event notification efficiency

    if (!checkThread.IsAlive)

    checkThread.Start();

    }

    catch(SocketException)

    {

    OnConnectCompleted(false);

    }

    }

The two methods     should actually be called first, so it is appropriate to start the detection thread with them. In addition, if the thread starts, it must also stop. So I rewrote Close method

    new public void Close()

    {

    if(checkThread.IsAlive) // first abort the thread and then close the connection

    checkThread.Abort();

    base.Close();

    sockState = SocketState.Disconnected;

    OnSocketClosed();

    }

    then the rest of the work is how to detect the socket, Socket class has a static method Select, it can detect the state of many sockets, but here only need to detect one, so directly use Socket Poll method Socket, Poll specific usage can see MSDN, I use the code here to explain my detection method
socket
    while(true) // loop check

    {

    if (sockState == SocketState.Disconnected) // if
is not currently connected
    {

    if (Poll(500, SelectMode.SelectWrite))

    OnConnectCompleted (true); // if the state is writable, the connection is successful
    }

    else if(sockState == SocketState.Listenning)

    {

    if (Poll(500, SelectMode.SelectRead)) // if the socket is found to have data readable in the listening state, it can be called Accept to accept the connection

    OnAcceptConnection();

    }

    else // here sockState = SocketState.Connected

    {

    if (Poll(500, SelectMode.SelectWrite)) // data can be sent if there is writable state
    OnDataCanSend();

    if (Poll(500, SelectMode.SelectRead)) //
if there is a readable state
    {

    if (Available > 0) // if there is data readable, Receive can be called to accept data

    OnDataCanReceive(Available);

    else

    {

    OnSocketClosed (); // no data to read means the connection has closed

    break;

    }

    }

    }

    // if there is no connection and an error state, the connection fails

    if (sockState == SocketState.Disconnected && Poll(500, SelectMode.SelectError))

    OnConnectCompleted(false);

    }

The OnXXX method here is the method that performs the event notification, and these methods can be overridden in derived classes to get the event notification directly without needing to hang up the event notification handler of the sector (virtual functions like MFC's OnAccept). But the derived set of functions calls the corresponding methods of the base class. Unfortunately, I did not override the Socket.Accept method to return an TcpEventSocket, which should be more complete. Unfortunately, I do not know how to do this.

The     event notification mechanism is almost complete, all that is missing is a lot of testing (I did the simplest tests a few times, shame on me!! ^_^)

If you have any questions, please contact yzx110@bit.edu.cn

Related articles: