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