Issue with socket recieve
Tim
tim.oliver at tutanota.com
Wed Jan 20 21:31:54 UTC 2021
Hi all,
I'm having a really terrible bug that seemed to come from nowhere
and is really hard to narrow down. I have a threaded message
service that works via local TcpSocket. Every time I run it,
either an error saying:
>Unable to open 'recv.c': Unable to read file
>'/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c'
>(Error: Unable to resolve non-existing file
>'/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c').
when socket.receive() is called. Sometimes I get the same thing
but for socket.accept() instead (different file). This seems to
generate a core.exception.InvalidMemoryOperationError that I
can't catch.
Yesterday, this came up after a couple of minutes of the program
running, now it happens straight away. I haven't touched this
class in a week or so and can't think of why all of a sudden it
has come up with this issue. Code dump below
---------------------------------------------
>module message_service;
>
>import std.stdio;
>import std.socket;
>import core.thread;
>
>
>/**
>Threaded socket manager to serve inter-service communication
>
>Calls delegates when the appropriate command is received
>*/
>class MessageService : Thread{
> /// The socket over which communication is possible
> private Socket server;
> /// The connection to the client that sends commands
> private Socket client;
> /// Associative array of command strings and relative
> functions to call
> private void delegate()[string] commands;
> /// Global buffer. Holds the command being recieved
> private char[1024] buffer = 0;
>
>
> ///
> this(ushort port, void delegate()[string] _commands){
> commands = _commands;
> server = new TcpSocket();
> server.setOption(SocketOptionLevel.SOCKET,
> SocketOption.REUSEADDR, true);
> server.bind(new InternetAddress(port));
> writefln("Message service started on port %d", port);
> super(&mainLoop);
> start();
> }
>
>
> /// Loops over polling the client socket for commands
> void mainLoop(){
> while(true){
> pollMessages();
> }
> }
>
>
> /**
> Polls the client socket for characters to build up the
> message buffer
>
> When a string command is found, it calls the appropriate
> function
> */
> void pollMessages(){
> server.listen(1);
> if(client is null) client = server.accept();
>
> // Add to the message buffer
> auto buffLength = client.receive(buffer);
>
> if(buffLength){
> auto message = cast(string) buffer[0 .. buffLength];
>
> foreach(cmd; commands.byKey){
> if(cmd == message){
> // Reset the message buffer
> buffer = 0;
> commands[cmd]();
> return;
> }
> }
> }
> }
>}
More information about the Digitalmars-d-learn
mailing list