netfreak
netfreak

Reputation: 63

Segmentation fault trying to send message to client from server

I need to send a message to a client and then the client have to respond with an option. I get till the client and server connects, but both program end with "Segmentation Fault". Does anyone knows what this error means? Can someone give an idea to how to create a code that will make client and server interact. After receiving the option chosen by the client the server have to analyze it and send again a result to client.

My codes are:

Server

    int
main(int argc, char **argv)
{
    int                 listenfd, connfd;
    socklen_t           len;
    struct sockaddr_in  servaddr, cliaddr;
    char                buff[MAXLINE];
    time_t              ticks;
    char                message[MAXLINE]="This is the server";
    char                temp_scale[2];
    char                recvdata[MAXLINE + 1];

    listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*----------------------------------------------------*/
    servaddr.sin_port        = htons(5555); 

    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
    Listen(listenfd, LISTENQ);

    for ( ; ; )
    {
        len = sizeof(cliaddr);
        connfd = Accept(listenfd, (SA *) &cliaddr, &len);

        printf("Connection from %s, port %d\n",
               Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
               ntohs(cliaddr.sin_port));


        snprintf(message, sizeof(message), "%s\r\n");
            Writen(connfd, message, strlen(message));
            while ( (n = read(connfd, recvdata, MAXLINE)) > 0)
            {
             recvdata[n] = 0;   /* null terminate*/
             if (fputs(recvdata, stdout) == EOF)
                 err_sys("fputs error");
            }
             if (n < 0)
          err_sys("read error");

           Close(connfd);
    }
}

Client

int
main(int argc, char **argv)
{
    int                 sockfd, rd;
    socklen_t           len;
    char                recvline[MAXLINE + 1];
    struct sockaddr_in  servaddr, cliaddr;
    char  scale[2];

    /*if (argc != 2)
        err_quit("usage: a.out <IPaddress>");*/

    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        err_sys("socket error");

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port   = htons(atoi(argv[2])); /*port passed through command line*/
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) /*The client translates the server address, passed on the command line*/
        err_quit("inet_pton error for %s", argv[1]);


    if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
        err_sys("connect error");

    len = sizeof(cliaddr);
    Getsockname(sockfd, (SA *) &cliaddr, &len);
    printf("Local Address is: %s\n",
           Sock_ntop((SA *) &cliaddr, sizeof(cliaddr))); 

    printf("Iniciando read...\n");
    while ( (rd = read(sockfd, recvline, MAXLINE)) > 0)
    {
        recvline[rd] = 0;   /* null terminate*/
        if (fputs(recvline, stdout) == EOF)
            err_sys("fputs error");
    }
    if (rd < 0)
     err_sys("read error");

    printf("Enter option 'A' or 'B'");
    send_scale(sockfd);

    exit(0);
}

Thanks

Upvotes: 1

Views: 3783

Answers (3)

user2561272
user2561272

Reputation: 11

I don't know if it might help, but in C the null termination for strings is '\0', when you print your response:

recvdata[n] = 0;   /* null terminate ----> this must be '\0'*/
if (fputs(recvdata, stdout) == EOF)
err_sys("fputs error");

you pad it whith a "0", so it will probably lead you to a segfault when fputs parse your string in order to print it.

Hope it helps!

Upvotes: 1

WhozCraig
WhozCraig

Reputation: 66214

Your server is probably faulting because of this:

snprintf(message, sizeof(message), "%s\r\n"); // <== no parameters

It is flat-out wrong. The snprintf() call has a format specifier that is expecting a char * to a null-terminated string, and you're passing it absolutely nothing. It is therefore grabbing a random value out of the stack, treating it as a pointer, and dereferencing it in attempt to fulfill the formatted request.

Without knowing the details of the API you're using (it clearly isn't standard BSD sockets just by the names alone) there isn't much more to go on.

Upvotes: 2

Jonas Bystr&#246;m
Jonas Bystr&#246;m

Reputation: 26169

Run your code in a debugger (for example gdb ./a.out) and find out in no time.

Upvotes: 2

Related Questions