socket connection getting closed abruptly with code 141
Asked Answered
F

3

5

What im trying to do is connect to a remote server , read contents from a file on the local machine and send it over to the server. Then capture the server response and save it. I put the GET command in a text file and am trying get the results of the same. Here is some part of the code. Im doing this using sockets and C.

if ( inet_pton(AF_INET,ip, &(nc_args->destaddr.sin_addr.s_addr)) <= 0 )
    printf("\n\t\t inet_pton error");


if (connect(sockfd, (struct sockaddr *) &nc_args->destaddr, sizeof(&nc_args->destaddr)) < 0)
{
    printf("\n\t\t Connection error");
    exit(1);
}
puts("\n\t\t Connection successful to ...");

// file parameter is taken from command line and passéd to this function

fp = fopen(file,"rb");
if ( fp == NULL)
{
    printf("\n\t\t File not found");
    exit(3);
}

else
{
    printf("\n\t\t Found file %s\n", file);

    fseek(fp, 0, SEEK_END);
    file_size = ftell(fp);
    rewind(fp);

    //allocate memory to the buffer dynamically

    buffer = (char*) malloc (sizeof(char)*file_size);
    if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
    for (i=0 ; i<sizeof(buffer); i++)
    {
        printf("\n\t\t %s", buffer);
    }
    printf("\n\t\t File contains %ld bytes!\n", file_size);
    printf("\n\t\t Sending the file now");
}


while (1)
{
    bytes_read = fread(buffer,1, file_size, fp);
     printf("\n\t\t The bytes read is %zd", bytes_read);
    if (bytes_read == 0) // We're done reading from the file
      {
          printf("\n\t\t The bytes read is %zd", bytes_read);
          break;
      }
    if (bytes_read < 0)
    {
        printf("\n\t\t ERROR reading from file");
    }

    void *p = buffer;

    while (bytes_read > 0)
    {
        ssize_t bytes_written = send(sockfd, buffer, bytes_read,0);
        if (bytes_written <= 0)
        {
           printf("\n\t\t ERROR writing to socket\n");
        }
        bytes_read -= bytes_written;
        p += bytes_written;
        printf("\n\t\t Bytes %zd written", bytes_written);
    }
}

printf("\n\n\t\t Sending complete.");

What is happening here is that i get the message "connection successful", then it displays "sending the file now" and then the program quits unexpectedly. if i do echo $? i get 141 as the exit code. I am trying to connect from my server to a different server at work and get the results. These two can communicate correctly, and i can run the GET command from command line without issues. Its just not working from the code. Can someone let me know what the issue could be ?

Followup answered 18/9, 2013 at 19:23 Comment(0)
I
12

On Linux, and probably other Unixes, the return code encodes a signal that the process received. Here it is 141 - 128 so 13 which corresponds to SIGPIPE.

If you don't want that signal to be raised because you capture the error return of send, anyhow, on Linux you can use MSG_NOSIGNAL in the flags argument to send to inhibit that signal. On other platforms you might have to program more complicated signal handlers to deal with that situation.

Impudicity answered 18/9, 2013 at 19:50 Comment(5)
why do you subtract the return code from 128? The reutnr value "141" is the number of bytes sent. Otherwise, if there were an error, it would reutnr -1, and you'd have to check errno for the error information. man7.org/linux/man-pages/man2/sendmsg.2.htmlDagmardagna
@Magn3s1um the shell adds 128 so you can distinguish between exit codes (usually low numbers) and fatal signals (also low numbers). Otherwise death by SIGHUP would look the same as exit(1)Naamann
I see, he's checking it in the shell. Missed htat partDagmardagna
hit same thing, quickly fixed it due to this SO anwer, so +1.Kalidasa
Thank you for this answer. I would never have figured out why my program was silently terminating without this!Scrabble
N
1

sizeof(&nc_args->destaddr) is the wrong thing to pass to connect. It wants the size of the address, not the size of a pointer to the address.

And this loop:

for (i=0 ; i<sizeof(buffer); i++)
{
    printf("\n\t\t %s", buffer);
}

is baffling. buffer is a pointer, as we can see from when it was assigned a vlue returned by malloc. So its size is going to be 4 or 8 bytes on 32-bit and 64-bit architectures respectively; not related to the size of the malloc'ed object it points to. The loop runs 4 or 8 times, and prints... the same thing each time. Why?

Naamann answered 18/9, 2013 at 19:53 Comment(1)
okay that was just for testing, i was trying out some stuff, irrelevant to the goal. I also changed the connect function arguments, buts still getting the same errorFollowup
C
0

Well for me, the issue was that I was calling the send() function with the wrong socket file descriptor.

int sockfd = socket(...);
bind(...);
listen(...);
int new_sockfd = accept(...);


// wrong method: calling send() function with wrong socket file descriptor
send(sockfd ,...);

// right method: calling send() function with socket file descriptor retrieved from accept()
send(new_sockfd, ...);
Challah answered 14/6 at 1:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.