Thread: 3 Way UDP chat program segmentation fault and other things wrong

  1. #1
    Registered User
    Join Date
    Dec 2012
    Posts
    4

    3 Way UDP chat program segmentation fault and other things wrong

    I am having some difficulty with this program. Right now I am running into a segmentation fault whenever anything is sent to the server. I also need to create a database to store those that enter the chat so that private messages can be sent to them but I have no idea how I should go about doing that. I believe the client is 99% of the way done, I just need to uncomment the one line (sending username to server for database). The server is where I am having difficulty I believe. I will provide the code.

    How do I get rid of the segmentation fault? How should I create the database? How do I parse out the ".send" and the username?

    Any help will be greatly appreciated. I have been working on this program for 3 weeks now and it is driving me crazy. I have never used C before only C++ and I have never done any socket programming. I also am not good with linux so if there are any commands you suggest me to use please explain them fully.

    Client

    Code:
    #include <stdio.h>
    #include <errno.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdlib.h>
    #include <string.h>
    #include <arpa/inet.h>
    
    extern int errno;
    
    int main (int argc, char *argv[]){
        char hname[255];
        struct sockaddr_in sin;
        struct sockaddr_in lin;
        socklen_t sinlength;
        socklen_t linlength;
        struct hostent *ph;
        int thesock;
        int len;
        long address;
        char host[40];
        char strinput[4096];
        char strinput2[4096];
        char buf[4096];
        char x;
        struct sockaddr_in to_addr;
        struct sockaddr_in from;
        socklen_t fromlen;
        int i;
        char username[20];
        int pid;
        char message;
        int s;
    
        
        if (argc != 3){
            printf("Usage:   ./a.out 172.21.24.1 port\n");
            exit(1);
        }
        else{
            strcpy(host, argv[1]);
        }
        
        if ((ph = gethostbyname (host)) == NULL){
            switch (h_errno){
                case HOST_NOT_FOUND:
                    fprintf(stderr, "%s: no such host %s\n", argv[0], host);
                    exit(1);
                case TRY_AGAIN:
                    fprintf(stderr, "%s: host %s, try again later\n", argv[0], host);
                    exit(1);
                case NO_RECOVERY:
                    fprintf(stderr, "%s: host %s   DNS ERROR\n", argv[0], host);
                    exit(1);
                case NO_ADDRESS:
                    fprintf(stderr, "%s: No IP address for %s\n", argv[0], host);
                    exit(1);
                default:
                    fprintf(stderr, "Unknown error: %d\n", h_errno);
                    exit(1);
                }
            }
        else {
            memcpy ((char *) &sin.sin_addr, (char *) ph ->h_addr, ph -> h_length);
            sin.sin_family = PF_INET;
        }
        
        i = gethostname(host, len);
    
        sin.sin_port = atoi(argv[2]);
        
        if ((s = socket (PF_INET, SOCK_DGRAM, 0)) < 0) {
            perror ("socket");
            exit(1);
        }
        
        lin.sin_family = PF_INET;
        lin.sin_addr.s_addr = INADDR_ANY;
        lin.sin_port = 0;
    
        linlength = sizeof(lin);
        
        if (bind(s, (struct sockaddr *) &lin, linlength) < 0){
            perror ("bind");
            exit(1);
        }
        
        if (getsockname(s, (struct sockaddr *) &lin, (socklen_t *) &linlength) < 0){
            perror ("getsockname");
            exit(1);
        }
        
        printf("What is your username?\n");
        fgets(username, 20, stdin);
        
        len = sizeof(hname);
        sinlength = sizeof(struct sockaddr_in);
    //    sendto(s, username, strlen(username), 0, (struct sockaddr *) &sin, sizeof (struct sockaddr));
        
        printf("\n");
        printf("You can send any text that you want. There are 2 special commands.\n");
        printf(".send <username> = send a private message to the username specified.\n");
        printf("(DO NOT INCLUDE <> IN THE COMMAND\n");
        printf(".quit = quit the program.\n");
        printf("\n");
    
        while(1){
            pid = fork();
            if (pid==0){
                recvfrom(s, buf, 4095, 0, (struct sockaddr *) &from, &fromlen);
                buf[message] = '\0';
                printf("\n(%s, %d) said : ", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
                printf("%s", buf);
                printf("\n");
                printf("\n");
            }
            else {
                char * strinput2;
                fgets(strinput, 4095, stdin);
                if (strinput2 = strstr (strinput, ".quit")){
                    sendto(s, strinput2, strlen(strinput2), 0, (struct sockaddr *) &sin, sizeof (struct sockaddr));
                    recvfrom(s, buf, 4095, 0, (struct sockaddr *) &from, &fromlen);
                    printf("The Client is now closing.\n");
                    close(s);
                    while ('\n' != getchar()){
                        getchar();
                        exit(1);
                    }
                }
                else{
                    sendto(s, strinput, strlen(strinput), 0, (struct sockaddr *) &sin, sizeof (struct sockaddr));
                }
            }
        }
    }
    Server

    Code:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <stdlib.h>
    
    extern int errno;
    
    int main(int argc, char *argv[]){
        const char * message;
        int i;
        int s;
        int fd;
        int len;
        struct sockaddr_in sin;
        int sinlength;
        char buf[BUFSIZ];
        int buflen;
        char x;
        char strinput[50];
        struct sockaddr_in from;
        socklen_t fromlen;
    
        int pid;
    
        int action;
    
        if ((s = socket(PF_INET, SOCK_DGRAM,0)) < 0){
            perror("Socket");
            exit(1);
        }
        sin.sin_family = PF_INET;
        sin.sin_addr.s_addr = INADDR_ANY;
        sin.sin_port = 0;
        sinlength = sizeof(sin);
    
        if (bind(s, (struct sockaddr *) &sin, sinlength) < 0){
            perror("bind");
            exit(1);
        }
        
        if (getsockname(s, (struct sockaddr *) &sin, (socklen_t *) &sinlength) < 0){
            perror("getsockname");
            exit(1);
        }
    
        printf ("Socket is using port %d\n", sin.sin_port);
        printf ("The Server is now running.\n");
    
        while(1){
            recvfrom(s, buf, buflen, 0, (struct sockaddr *) &from, &fromlen);
    //        buf[message] = '\0';
            message==buf;
            if (message = strstr(message, ".quit")){
                char *reply;
                reply = "Acknowledged Quit command";
                printf ("(%s , %d) has left the forum");
                sendto(s, reply, strlen(reply), 0, (struct sockaddr *) &from, fromlen);
                close(s);
                while ('\n' != getchar()){
                    getchar();
                    exit(1);
                }
            }
            if (message = strstr(message, ".send")){
                //parse .send
                    //parse username
                        sendto(s, message, strlen(message), 0, (struct sockaddr *) &from, fromlen);
            }
            else {
                printf("(%s , %d) said : ", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
                sendto(s, message, strlen(message), 0, (struct sockaddr *) &from, fromlen);
            }
        }
    }

  2. #2
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    compile your program with the -g flag, ie: gcc -g -o myprogram sourcecode.c

    Then run it in gdb:
    gdb ./client
    gdb ./server (in another terminal)

    When gdb starts, type 'r' for (run) and hit enter, then when it segfaults, type 'bt' for "backtrace" and it will show you the lines of code that caused
    the segfault. Post that information here if you cant figure it out.

    If you dont know what 'gdb' is, google and read up on it.

  3. #3
    Registered User
    Join Date
    Dec 2012
    Posts
    4
    I have the client on a different linux machine than the server. does that matter for gdb?

  4. #4
    Registered User
    Join Date
    Dec 2012
    Posts
    4
    Program received signal SIGSEGV, Segmentation fault.
    0x00684ac8 in __strstr_sse42 () from /lib/libc.so.6
    (gdb) bt
    #0 0x00684ac8 in __strstr_sse42 () from /lib/libc.so.6
    #1 0x08048800 in main ()

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Code:
    message==buf;
    Come again? That's a comparison there, not an assignment, therefore accomplishing nothing. Your next line

    Code:
    if (message = strstr(message, ".quit")){
    then uses the uninitialized message variable, which is undefined behavior.

    And another cross-poster.
    Last edited by rags_to_riches; 12-02-2012 at 06:16 AM.

  6. #6
    Registered User
    Join Date
    Dec 2012
    Posts
    4
    Quote Originally Posted by rags_to_riches View Post
    Code:
    message==buf;
    Come again? That's a comparison there, not an assignment, therefore accomplishing nothing. Your next line

    Code:
    if (message = strstr(message, ".quit")){
    then uses the uninitialized message variable, which is undefined behavior.

    And another cross-poster.
    Changed it to message=buf; still doesn't work. Still getting the segmentation error.

    Also I have posted this in more than one forum because I am not getting the help that I need, so I am trying different communities to see if they will help.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Code:
            pid = fork();
            if (pid==0){
                recvfrom(s, buf, 4095, 0, (struct sockaddr *) &from, &fromlen);
                buf[message] = '\0';
    1. Calling fork() for every single line of input is a sure way to blow things up. Why do you even need this.
    2. What is stored in message? It seems to be an uninitialised value to me.
    3. message is only a char, but buf is 4096 bytes long. It simply cannot index 127 (or 255 if chars are unsigned on your machine).
    4. recvfrom RETURNS the number of bytes read, or -1 on error; Read the manual page.
    Code:
    ssize_t n = recvfrom(s, buf, 4095, 0, (struct sockaddr *) &from, &fromlen);
    if ( n > 0 ) {
      buf[n] = '\0';
      // do stuff with buf
    }
    Client-Server Background
    Familiarise yourself with these, then start making SMALL changes towards what you want to do.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 09-21-2012, 05:19 AM
  2. Where i'm wrong ? getting a segmentation fault
    By dayanike in forum C Programming
    Replies: 2
    Last Post: 05-23-2012, 12:30 PM
  3. Replies: 7
    Last Post: 03-17-2011, 10:55 AM
  4. Can anyone show me what is wrong here? Segmentation fault
    By BigFish21 in forum C Programming
    Replies: 17
    Last Post: 11-22-2007, 01:23 AM
  5. Segmentation fault on my program
    By blackswan in forum C Programming
    Replies: 2
    Last Post: 05-11-2005, 04:47 PM

Tags for this Thread