Friday, June 20, 2014

Homemade Internet Service Relay (VIII)

Now we switch to the highest level of abstraction that we provides. To use the library, the client must first establish a TCP connection, and then constructs a Connection object.

public Connection(Socket socket, ConnectionType connectionType)

Since the connection is shared, one cannot send/receive data through the Connection directly, instead, one create Channels. On the client side (i.e. initiator), he can simply create a channel by calling Connect.

public Channel ConnectChannel()

Unlike TCP, the call is synchronous because the connection is already established. Currently we do not check if the other side is ready to accept this connection, we simply assumes the server eventually will. This could be improved in the future.

On the other hand, the server side will need to wait for a Channel establishment request, this is done by calling Accept

public IAsyncResult BeginAcceptChannel(AsyncCallback callback, object state)
public Channel EndAcceptChannel(IAsyncResult ar)

This call is necessarily asynchronous not because it involves I/O, but because it blocks on waiting.
Channel itself is just a Stream. This design make it very easy for other stream processing code (e.g. serialization) to use the library without modification. In addition, it provides a teardown that stop sending data to model TCP one-way shutdown.

public void StopSending()
public IAsyncResult BeginStopSending(AsyncCallback callback, object state)
public void EndStopSending(IAsyncResult ar)
public Task StopSendingAsync()

In the next post we will talk about how the connector work inside.

1 comment :

  1. The connect() issue does backfire. For VNC - the client does not send anything after connect. In this model - it does not send any message to the another side of the tunnel, so the client just keep waiting.

    A simple fix is made by simply sending an empty packet - note that the empty packet indicate a close, so special care has to be taken to make sure the another side does not close the channel on the first zero sized packet.

    ReplyDelete