`Socket.receive` providing arbitrary packet sizes and hanging without sending EOF
Unazed Spectaculum
unazed at spec.org
Thu Dec 14 19:55:46 UTC 2017
On Thursday, 14 December 2017 at 00:09:39 UTC, Ali Çehreli wrote:
> On 12/13/2017 11:39 AM, Unazed Spectaculum wrote:
> > ubyte[] receiveBytes(T)(T socket, size_t receiveCount)
> > {
> > ubyte[] buffer = new ubyte[receiveCount];
> > size_t count = socket.receive(buffer);
>
> Don't trust code you find on newsgroups. :o) You have to check
> the returned value first. According to documentation, it can
> return Socket.ERROR:
>
> https://dlang.org/phobos/std_socket.html#.Socket.receive
>
> > there is always a superfluous chunk
> > which is awaiting data.
>
> Can you show with complete code? Perhaps the stream is in
> blocking mode?
>
> > No matter what way I try; my code doesn't seem to know when
> to quit
> > regardless of the check. Also for the arbitrary packet sizes,
> I would've
> > expected that if I received N bytes X times, the first X-1
> times would
> > be perfectly N not some unusual integer.
> > Simply put, say I'm receiving 1024 bytes 5 times. The length
> of each
> > item on the stack looks like:
> >
> > [720,
> > 490,
> > 1024,
> > 103
> > ]
>
> Posix read(2) man page says
>
> "It is not an error if this number is smaller than the number
> of bytes
> requested; this may happen for example because fewer bytes are
> actually
> available right now (maybe because we were close to
> end-of-file, or because
> we are reading from a pipe, or from a terminal), or because
> read() was
> interrupted by a signal."
>
> Ali
void main()
{
auto socket = new TcpSocket();
setupSocket(socket, "0.0.0.0", 6969);
writefln("Listening: %s", socket.localAddress);
while(true)
{
Socket client = socket.accept();
debug(1) writefln("Client: %s", client.remoteAddress);
auto data = receiveAll(client);
writeln(data);
JSONValue json;
try {
json = parseJSON(data);
} catch (JSONException e) {
debug(1) writefln("Failed parsing data as JSON, aborting.\n||
%s", e);
client.close();
continue;
} catch (Exception e) {
debug(1) writefln("Client caused exception:\n||%s", e);
client.close();
continue;
}
if (!verifyValues(json))
{
debug(1) writefln("Client missed out important key fields:
%s", client.remoteAddress);
client.close();
continue;
}
debug(1) writeln("Client transacted successful JSON packet.");
writefln("%s:\n\tFilename: %s\n\tMethod: %s\n\tData length: %d",
client.remoteAddress,
json["filename"],
json["method"],
data.length
);
if (json["method"].str == "store")
storeData(json["filename"].str, json["data"].str);
else if (json["method"].str == "retrieve")
retrieveData(client, json["filename"].str);
client.close();
}
}
This is the only function which has a call to `receiveAll`, also
yeah I don't typically check return codes for error values, I
just assume it'll all work and if it doesn't a fresh restart will
fix it; but I'll include it in my code just in case.
More information about the Digitalmars-d-learn
mailing list