2014-04-04 26 views
0
enum recstate { 
    initial 
}; 

int num_clients = 0; 

static void addclient(int fd, struct in_addr addr){ 
    struct client *p = (struct client *) malloc (sizeof(struct client)); 
    if (!p) { 
     fprintf(stderr, "out of memory!\n"); 
     exit(1); 
    } 
    printf("Adding client %s\n", inet_ntoa(addr)); 
    p->fd = fd;   
    p->next = top;   
    p->state = initial; 
    top = p;    
    num_clients++; 
} 

struct client { 
    int fd;    // socket descriptor for this client 
    enum recstate state; // current state of data transfer for this client 
    struct client *next; // a pointer to the next client in the list 
    struct in_addr ipaddr; 
} *top = NULL; 

int main(int argc, char* argv[]){ 
    int listenfd, clientfd, maxfd, nready; 
    struct client *p; 
    struct sockaddr_in self, client; 

    listenfd = socket(AF_INET, SOCK_STREAM, 0); 
    memset(&self, '\0', sizeof(self)); 
    self.sin_family  = AF_INET; 
    self.sin_addr.s_addr = INADDR_ANY; 
    self.sin_port  = htons(PORT); 

    if (bind(listenfd, (struct sockaddr *) &self, sizeof(self))){ 
     perror("bind"); 
     exit(1); 
    } 

    if (listen(listenfd, 5) < 0){ 
     perror("listen"); 
     exit(1); 
    } 

    while (1){ 
     fd_set allset, rset; 
     FD_ZERO(&allset);   
     FD_SET(listenfd, &allset); 
     maxfd = listenfd;   

     rset = allset; 

     for (p = top; p; p = p->next){ 
      FD_SET(p->fd, &allset); 
      if (p->fd > maxfd){ 
       maxfd = p->fd;  
      } 
     } 

     if(FD_ISSET(listenfd, &rset)){ 
      printf("Listenfd is ready\n"); 
      len = sizeof(client); 

      if ((clientfd = accept(listenfd, (struct sockaddr *) &client, &len)) < 0){ 
       perror("accept"); 
       return(1); 
      } 

      else { 
       printf("Connection from %s\n", inet_ntoa(client.sin_addr)); 
       addclient(clientfd, client.sin_addr); 

       FD_SET(clientfd, &rset); 
       printf("clientfd has been added to fdset\n"); 

       if(p->state == initial){ //cannot get into this if statement 
        printf("now in initial state\n"); 

        nready = select(maxfd + 1, &rset, NULL, NULL, NULL); 

        if(nready == 0){ 
         printf("timeout happened\n"); 
         continue; 
        } 
        else if(nready == -1){ 
         perror("select"); 
         continue; 
        } 
        else if (nready > 0){ 
         printf("Data is now available.\n"); 
         continue; 
        } 

        if (FD_ISSET(listenfd, &rset)){ //returns a value for fd in rset 
         //read data into file 
        } 
       } 
      } 
     } 
    } 
} 

這是我的服務器代碼的一部分。 我試圖從客戶端發送文件到服務器,但是當我從客戶端發送文件時,服務器將執行,直到if(p-> state == initial)語句之上,並掛在那裏。當我終止服務器時,它會給我一個分段錯誤:11錯誤。 另外,我在初始狀態中使用select()以允許多個客戶端同時連接。 不知道我哪裏錯了,任何幫助將不勝感激。 謝謝。分段錯誤:11服務器/客戶端

+1

它看起來像p是NULL在那個if語句的地方?如果是這樣(或者如果p設置爲其他一些無效值),這可能會解釋不當行爲。你可以在if之前放一個printf(「p =%p \ n」,p),並在取消引用之前查看它的值。 –

+0

好吧,所以我只是跑了它,顯然,p = 0x0 – user3291818

+0

那麼我將如何設置p!= NULL? – user3291818

回答

0

for (p = top; p; p = p->next){

除非我記錯了,你循環,直到pNULL

if(p->state == initial){

,然後取消引用pKABOOM