分段故障:11服务器/客户端

时间:2014-04-04 21:14:25

标签: c sockets if-statement client-server

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-&gt; state == initial)语句的上方,并挂起。当我终止服务器时,它会给我一个分段错误:11错误。 此外,我在初始状态内使用select()以允许多个客户端同时连接。 不知道我哪里出错了,任何帮助都会非常感激。 感谢。

1 个答案:

答案 0 :(得分:0)

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

除非我弄错了,否则直到pNULL

为止

if(p->state == initial){

然后解除引用p。 的 KABOOM