Totally perplexing SFML socket receive bug, cant find a logical foot hold to start debugging

My application works as a server or a client, its a gui with a socket multiplexer that will launch connections in lots of threads.

A socket is connected and then a thread has send and receive being called repeatedly, it is a non blocking socket and send and receive are covered by a mutex lock.

data can be successfully sent and received, im having no problem communicating both ways with connections so long as my received output is sent out the console, this isn't good enough, I made a gui with an SFML library.

everything works unless I take a string of a data structure that has come from the received function, if I was to output that to the console fine, if I put it through the GUI i get a segfault.

I dont get a segfault if the text output to the GUI is shorter than the first string to ever come through, after that its displayed fine.

by shorter I mean less chars.

this is my receive function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

void sockWrapper::receive(){

    char data[8000];
    std::size_t received;

    // TCP socket:
    if(socket.receive(data, sizeof(data), received) != sf::Socket::Done){

         
    }else{

        std::string temp;
        temp = ((std::string) data).substr( 0, received);     
        messageStack.push_back(temp);
        std::cout<< temp << std::endl;
    }
}


size_t is global, I suspect maybe that received isnt being re-sised properly, this function is called in runConnection(), run connection is launched in a thread on connection of hte socket:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void sockWrapper::runConnection(){

    while(getAlive()){

        if(getToSend()){

            //protect thread from using stack at wrong time
            mutex.lock();
            send(postMessage());

            messageStack.push_back( getName() + ": " + message); //<- this is the message being put on a handling stack 

            //free mutex
            mutex.unlock();

            //sets message back to ""
            message = "";

            //sets flag to post something back to false
            setToSend(false);
        }


        sf::sleep(sf::milliseconds(10));

        //protect receive functions
        mutex.lock();

        //launches thread of thread for one run, this is normally for if socket is blocking
        receiveThread.launch();

        //free up lock again
        mutex.unlock();
    }
}
 


the messages are put on a stack structure and are called by the application with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//returns last message in stack to application while guarding process with mutex locks
std::string sockWrapper::getMessage(){

    std::string temp; 

    //mutex avoids change in size of stack while runConnection i
    mutex.lock();

    if(!messageStack.empty()){

        temp = messageStack.back();
        messageStack.pop_back();
        mutex.unlock();

        return temp;
    }

    mutex.unlock();

    return "bad message stack protocol, out of range error likley!";
}

If I send a substring of temp to be smaller than the first string to come through the program works, if I send something else entirley like I replace temp with "fluffyBalls" then fluffyBalls will be output each time something comes through the connection, nothing ever seems to go wrong.

I have tried and tested many things, the only thing thats sure is the text displayed on the gui have to be smaller than whatever first comes through the network.

The whole code can be found at github -> https://github.com/ma302jh/assignment2
Last edited on
size_t is global, I suspect maybe that received isnt being re-sised properly, this function is called in runConnection()
std::size_t is a type supplied by the standard library.
received is a local variable that doesn't exist outside the function.
Not called in runConnection(), unless it's called indirectly by some other function.

I don't see anything really wrong with receive except the possible undefined behavior with the construction of a string from a non-nul terminated C string. I don't think I'd choose to keep an 8000 element array on the stack, either.

1
2
3
4
5
6
7
8
9
10
void sockWrapper::receive(){
    std::vector<char> buffer(8000);
    std::size_t received=0;

    // TCP socket:
    if(socket.receive(buffer.data, buffer.size(), received) == sf::Socket::Done) {
        std::string str(buffer.data(), 0, received);
        messageStack.push_back(str);
    }
}


Also, if you need to use mutexe (can you find a better name?) to guard write access to the messageStack member elsewhere, why are you not doing it here? Why is mutex public? Why is messageStack public?

Why? Why? Why?
oh cos I was copy pasting stuff all over the place during testing, I wanted to see what would change, I was perplexed enough to mess with things to see if it would kick up any behavior that would offer a clue.

Also using gdb I was moving stuff to see what was what, I am tottaly new to these pragmactices.

EDIT: implemented your changes, looks much neater however the problem remains the same!!, what else could the problem be? would calling receive again too soon cause some weird ass error where the rest of the strings have to have the same memory size as the first one?

EDIT2: further experimentation revealed that its always the size of the first string that is SENT!!

here is the send string:


1
2
3
4
5
6
void sockWrapper::send( std::string _message){

    _message += '\0';
    const char* toSend = _message.c_str();
    socket.send( toSend, strlen(toSend));
}


still have not made any progress
Last edited on
Topic archived. No new replies allowed.