[erlang-questions] ssl:shutdown(Socket, write) unexpected behavior?

zxq9 zxq9@REDACTED
Thu Jun 9 02:32:09 CEST 2016


On Wednesday 08 June 2016 16:25:19 Jay Doane wrote:
> I'm working on an erlang network file copier that should be able to
> use either tcp or ssl, depending on its configuration.
> 
> The basic idea is that it listens on a specified port, and writes
> anything it receives to a file, then with the *same* connection,
> responds to the sender with some statistics, and finally closes the
> connection.  A demonstration version can be found here:
> https://gist.github.com/jaydoane/65dc6b005788af3c49e2866ea7d03f09
> 
> For basic tcp, this can be achieved by the sender doing a
> gen_tcp:shutdown(Socket, write) after sending the payload, which -- if
> the receiving socket is configured with {exit_on_close, false} --
> closes the connection in the sending direction, but leaves it open to
> receive the response. For example, this test works:

In general it is not the easiest thing to manage several layers of the
communication stack as part of a single protocol. What I mean is, there
are several levels here, and the transport layer (TCP/UDP/SCTP -- which
is what TLS is supposed to be wrapping) is below the application layer
you are trying to build on top. So whether or not you *can* get the
effect you want by closing one direction on the connection from one side
and detecting that change on the other as an application-level signal
isn't really the point -- its probably not a good idea to use this as a
hidden protocol "verb".

For this kind of thing I usually add a 32-bit header that is the total
length to be sent in bytes, and have the receiver add up how much it is
receiving, and stop once it receives that much or times out in the middle.
At the moment your file transfer system has no indication which condition
is occurring:

* Did the other end finish sending, but improperly close its 'write'
  direction of the transport layer.
* Did your side improperly interpret the other side closing its 'write'
  direction. If so is this a driver issue over which you have no control?
* Did the other side drop off the network?
* Did the other side stall?
* Is that all there is to receive? (A few unknowns rolled into one...)

Having a known size is much more reliable and also allows you to be more
flexible with how you buffer the received data.

Now how to react?

Once Size == Received, then you initiate the stats response, and have the
receiver close the connection. Or you respond with the stats, receive an
ack from the sender, and then close the connection. Or whatever. My point
being that the application-level signal should not be the transport-layer
event.

You're getting close to a nice little utility there. :-) Keep at it!
Socket programming in Erlang can be a wonderful thing.

-Craig



More information about the erlang-questions mailing list