Search code examples
csocketstelnet

C socket read outputs empty string when using one line telnet statement


I have a problem reading a client input through a TCP socket using telnet and echo in one line. It only works when i input the message in a 'normal' telnet session:

Client Console

devbox cehrig # telnet 127.0.0.1 50231
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Test Message
Connection closed by foreign host.
devbox cehrig # echo "One Liner" | telnet 127.0.0.1 50231
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Connection closed by foreign host.
devbox cehrig # 

Server Console

Mon Apr  6 16:36:41 2015: Accepting connections...
Mon Apr  6 16:36:45 2015: Inbound connection from  127.0.0.1
Client msg: Test Message
Mon Apr  6 16:36:48 2015: Accepting connections...
Mon Apr  6 16:44:06 2015: Inbound connection from  127.0.0.1
Client msg: 
Mon Apr  6 16:44:06 2015: Accepting connections...

"Client msg" keeps being empty when trying to send data with echo "" | telnet ....

This is the function I'm using to read from the client socket:

void read_socket(int idntef, 
         config_t * cfg)
{
    int n;
    char * _buf = (char *) malloc(512*sizeof(char));
    char * _cor = (char *) malloc(512*sizeof(char));
    char * _out = _cor;

    bzero(_buf, 512);
    bzero(_cor, 512);


    if((n = read(idntef, _buf, 511)) < 0) {
        _print(stderr, "messages.socketreadfail", cfg, 1);
        _exit(0);
    }

    int x = 0;
    while(*_buf != '\n' && x++ <= 512) {
        *_cor++ = *_buf++;
    }

    printf("Client msg: %s\n", _out);
    fflush(stdout);
    shutdown(idntef, 2);
}

Does sbd has a hint for me, what to improve here?


Solution

  • There is no guarantee data will be sent in one block. You need to read in a loop until '\n' is found or buffer limit reached.

    Something like:

    size_t size=0;
    do {
        if((n = read(idntef, _buf+size, 512-size)) < 0) {
            _print(stderr, "messages.socketreadfail", cfg, 1);
            _exit(0);
        }
        size += n;
    } while(strchr(_buf, '\n') == NULL && size < 512);