服务器套接字挂在子proc上

时间:2017-03-11 01:39:05

标签: c sockets server multiprocessing

我在从服务器中抽取一些函数时遇到了一些麻烦。特别是我的解析功能在子进程内部很难调试,我甚至无法在gdb中跟随它,因为当我遵循子进程时服务器正在跳循环?我认为在我的文字中显示代码可能比编写上下文更容易..

主要产卵循环

while (1) { /* accepting client connections */
        addrlen = sizeof(client_addr);

        /* create worker and accept traffic on listen_sock */
        printf("Waiting for client connection\n");
        if ((worker_sock = accept(listen_sock, (struct sockaddr*) &client_addr, &addrlen)) < 0) {
            perror("Error accepting traffic on socket:"); continue;
        }

        inet_ntop(client_addr.ss_family, get_in_addr((struct sockaddr *) &client_addr), s, sizeof(s));
        printf("server: got connection from %s\n", s);

        if (!fork()) {                       // this is the child process
            close(listen_sock);               // child doesn't need the listener
            respond(worker_sock);             // send response to client
//            shutdown(worker_sock, SHUT_RDWR); // block connections
            close(worker_sock);               // destroy that old sock!
            exit(0);                          // exit proc
        }                                     // end of child proc
        close(worker_sock);                   // parent doesn't need this
    }

回应功能(由孩子召唤)

/* serve response for client request */
void respond(int worker_sock) {
    char *request[3], path[PATH_MAX] = {'\0'};
    char recv_data[SOCK_BUFF_DEF_READ] = {'\0'};
    char resp_data[SOCK_BUFF_DEF_WRITE] = {'\0'};
    ssize_t bytes_read = 0;
    int resourcefd;

    /* TODO: change this to terminate on client req flag (header w/ size of req) */
    /* read into buff full request */
    if ((bytes_read = recv(worker_sock, recv_data, SOCK_BUFF_DEF_READ, 0)) < 0) {
        fprintf(stderr, ("recv() error\n"));
    } printf("File: %s\nFunction: %s()\nLine Number: %d\nbytes_read: %d, MAX: %d\n",__FILE__,__FUNCTION__,__LINE__, bytes_read, SOCK_BUFF_MAX_READ);
    /* error checking buffer overflow checking */
    if (bytes_read == 0 || bytes_read > SOCK_BUFF_MAX_READ) {
        fprintf(stderr, ("recv() error\n"));
        /* send error response */
    }

    Request request00 = parseRequest(recv_data);

正在进行解析器的抽象

typedef struct request Request;
struct request {
    unsigned char    info;        /*   request method / proto     */
    char            *path;        /*   path to resource   */
    Dict            *headers;     /*   http headers       */
    char            *body;        /*   body of request   */
};


/* parse request line from a client request */
Request parseRequest(char *req) {
    int i;

    printf("processing client request\n");
    size_t *num_tokens = malloc(sizeof(size_t));           /* num of tokens */

    char **tokens = strsplit(req, " \r\n", num_tokens);     /* parse it */
    printf("File: %s\nFunction: %s()\nLine Number: %d\n",__FILE__,__FUNCTION__,__LINE__);
    printf("num_tokens: %zi\n", *num_tokens);

    for (i = 0; i < *num_tokens; i++) {
        printf("token: %s\n", tokens[i]);
    }

    printf("File: %s\nFunction: %s()\nLine Number: %d\n",__FILE__,__FUNCTION__,__LINE__);
    Request retreq = {
            .info = 0,                                      /* method, proto, validity */
            .path = (char *) malloc(sizeof(char *)),        /* request path or URI */
            .headers = initDict(50),                        /* limit to 50 headers */
            .body = (char *) malloc(sizeof(char *))         /* body of request */
    };


    return retreq;
}

我确定孩子已经挂在了strSplit函数上(我的strtok_r实现),但是该函数已经过彻底的测试,并且在我的其他实现中仍然有效,所以我很难理解为什么孩子的上下文在调用中有所不同这个函数,strsplit也发布在下面。

strSplit

char **strsplit(char *str, const char delims[], size_t *len) {
    char *save;              /* holds str_tok val btwn calls */
    char **result = '\0';    /* set result to NULL */
    char *tmp = strdup(str); /* leaves original str intact */
    size_t delims_size = strlen(delims);
    size_t count = 0;        /* number of main strings */
    size_t sub_count = 0;    /* number of substrings */

    /* get number of delims in str and malloc */
    while ((tmp = strstr(tmp, delims)) != NULL) {
        tmp += delims_size;
        count++;
    }
    result = malloc(sizeof(char*) * count);

    if (result) {
        /*  reset counter and tmp   */
        count = 0;
        free(tmp);
        tmp = strdup(str);
        /*   grab the first token   */
        char* token = strtok_r(tmp, delims, &save);
        result[count] = strdup(token);

        while (token) {
            token = strtok_r(NULL, delims, &save);
            if (token != NULL) {
                result[++count] = strdup(token);
            }
            else { /* set last ptr to NULL */
                result[++count] = '\0';
            }/* add one for trailing token */
        } *len = count;
    }
    else {
        *len = 0;
    }
    free(tmp);
    return result;
}

如果有人知道如何更好地调试这个我的全部耳朵..当设置gdb与“set follow-fork-mode child”时,它会尝试跟随孩子,但是父母跳出循环(它应该是无限直到信号停止它)并因此结束程序..

0 个答案:

没有答案