jimbo
jimbo

Reputation: 109

C structs help - I'm lost / BSD sockets

I'm a newbie to C and am a little lost.

So what am I doing?

What I'm trying to do?

Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <netdb.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_fw.h>
#include <pthread.h>
#define MYPORT 8080
#define BACKLOG 36600

struct thread_data {
    int new_fd;
    struct address_data adata;
};
struct address_data {
    unsigned long s_addr;
};
//---------------------------httpRequest Method------------------------ 
void* httpRequest(void* data) 
{ 
    struct thread_data me;
    me = *((struct thread_data*)data);

   printf("struct ip: %s\n", inet_ntoa(me.adata));
   printf("struct fd: %d\n", me.new_fd);

   pthread_exit(NULL);  //Existing from the threads. 
}
//**************************************************************************************************************** 
//Main Method------------------------------------------------------------------
int main (void) 
{ 
    int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd 
    struct sockaddr_in my_addr;    // my address information 
    struct sockaddr_in their_addr; // connector's address information 
    struct thread_data td;
    int sin_size; 
    struct sigaction sa; 
    int yes=1;
    pthread_t p_thread[3000]; 
    int thr_id,i=0;   

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
        perror("socket"); 
        exit(1); 
    }

    if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) { 
        perror("setsockopt"); 
        exit(1); 
    }

    // bzero((char *) &my_addr, sizeof(my_addr)); 
    my_addr.sin_family = AF_INET;         // host byte order 
    my_addr.sin_port = htons(MYPORT);     // short, network byte order 
    my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP 
    memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct

    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))== -1) { 
        perror("bind"); 
        exit(1); 
    }

    if (listen(sockfd, BACKLOG) == -1) { 
        perror("listen"); 
        exit(1); 
    }
    sa.sa_handler = sigchld_handler; // read all dead processes 
    sigemptyset(&sa.sa_mask); 
    sa.sa_flags = SA_RESTART; 
    if (sigaction(SIGCHLD, &sa, NULL) == -1) { 
        perror("sigaction"); 
        exit(1); 
    }


    while(1) 
    {  // main accept() loop 
        sin_size = sizeof(struct sockaddr_in); 
        if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr,&sin_size)) == -1) { 
            perror("accept"); 
            continue; 
        } 
    printf("Got connection from %s\n",inet_ntoa(their_addr.sin_addr));

    td.new_fd = (int *)&new_fd;
    td.adata = their_addr.sin_addr;

        //Creates threads.
        thr_id = pthread_create(&p_thread[i++],NULL,httpRequest,(void*)&td); 
   }
    return 0; 
}

When I get a connection, the program unexpectedly exits.

As you can see I've made the thread_data struct as a model to sockaddr_in. It'd be great, if you could point out where I'm going wrong. Thanks in advance.

Upvotes: 0

Views: 181

Answers (1)

Rafael Baptista
Rafael Baptista

Reputation: 11499

There are probably other errors. But at the very least:

int main (void) 
{ 
    struct thread_data td;

    while(1) 
    {
       thr_id = pthread_create(&p_thread[i++],NULL,httpRequest,(void*)&td); 
    }
    return 0; 
}

You have only one copy of td. Yet you pass the same one to multiple threads. So on the second request, you overwrite the same td you gave to the first thread.

Upvotes: 1

Related Questions