添加信号线程时,C接受客户端套接字“无效参数”错误

时间:2018-12-12 17:26:08

标签: c sockets networking signals

我正在做一个上课的项目,我陷入了一个问题。

我的项目每15秒需要一个计时器来打印数据。它还需要捕获程序的终止。为了处理这两个任务,我创建了一个信号线程并捕获SIGINT和SIGALRM(来自setitimer)信号。我在这里没有问题。

但是,我的服务器->客户端连接现在不再正常工作。我的套接字ID一直为-1,错误为“ Invalid Argument”。这对我来说没有任何意义,因为如果我禁用信号线程,一切都会再次正常。请粘贴下面的代码。

db.items.aggregate([
  { "$lookup": {
    "from": "fruits",
    "localField": "item_type_id",
    "foreignField": "item_id",
    "as": "fruits_details"
  }},
  { "$lookup": {
    "from": "books",
    "localField": "item_type_id",
    "foreignField": "item_id",
    "as": "books_details"
  }},
  { "$addFields": {
    "books_details": {
      "$cond": [{ "$eq": ["$item_type", "book"] }, "$books_details", {}]
    },
    "fruits_details": {
      "$cond": [{ "$eq": ["$item_type", "fruit"] }, "$fruits_details", {}]
    }
  }}
])

所以我得到的错误发生在这里:

void * signal_thread(void * arg) {


while (1) {
    int caught_signal;

    sigwait(&mask, &caught_signal);

    switch(caught_signal) {
    case SIGINT:
        puts("Server manually terminated!");
        int i;
        for(i = 0; i<clientCount; i++){
            send(socketIds[i], "ServerShutDown", 255, 0);
        }
        break;
    case SIGALRM:
        printf("CAUGHT SIGALRM\n");
        break;
    default:
        break;
    }
}
}

int main(void) {
    /* do the necessary setup, i.e. bind() and listen()... */
    int rc;
    pthread_t signal_tid;
    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigaddset(&mask, SIGALRM);
    rc = pthread_sigmask(SIG_BLOCK, &mask, NULL);

    if (rc != 0) 
        puts("Sig mask error");

    rc = pthread_create(&signal_tid, NULL, signal_thread, &mask);

    if (rc!= 0)
        puts("Sig thread error");




    struct itimerval timer;
    timer.it_value.tv_sec = 2;
    timer.it_value.tv_usec = 0;
    timer.it_interval.tv_sec = 2;
    timer.it_interval.tv_usec = 0;
    setitimer (ITIMER_REAL, &timer, NULL);


int socket_desc , client_sock , c;
    struct sockaddr_in server , client;
     int sockfd, newsocket, length;
     int port =  8778;
    //Create socket

    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }

    if(setsockopt(socket_desc, SOL_SOCKET, SO_REUSEADDR, &(int) {1}, sizeof(int)) < 0){
        perror("setsockopt failed");
    }

    bzero((char*) &server, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port =  htons(port);

    //Bind
    if( bind(socket_desc,(struct sockaddr *) &server , sizeof(server)) < 0)
    {
        //print the error message
        perror("bind failed. Error");
        return 1;
    }

    //Listen
    listen(socket_desc , 5);

     length = sizeof(struct sockaddr_in);


    //Accept and incoming connection
    puts("Waiting for incoming connections...");

    pthread_t thread_id;
      while( 1 )
    {
        int * socketPtr = malloc(sizeof(int));
        newsocket = accept(socket_desc, (struct sockaddr *) &client, (socklen_t *) &c);
        if (newsocket == -1) {
            perror("Error at accept..");
        }
        printf("Accepted new client connection!\n");
        socketIds[clientCount++] = newsocket;
        if( pthread_create( &thread_id , NULL ,  handle_connection , &newsocket) < 0)
        {
            perror("could not create thread");
            return 1;
        }


        //Now join the thread , so that we dont terminate before the thread
        //pthread_join( thread_id , NULL);

    }

    if (client_sock < 0)
    {
        perror("accept failed");
        return 1;
    }

    return 0;
}

接受错误..:无效的参数打印出来。

当我禁用此行时:

if (newsocket == -1) {
            perror("Error at accept..");
        }

错误停止。我不知道这个不相关的线程如何导致服务器客户端连接混乱。任何见识将不胜感激

编辑:解决了克里斯·特纳。我在长度arg中输入的字段有误。很奇怪以前的工作方式!

1 个答案:

答案 0 :(得分:0)

您永远不会为c分配一个明智的值,因此您在此处将随机垃圾传递给accept

    newsocket = accept(socket_desc, (struct sockaddr *) &client, (socklen_t *) &c);

它可能是合法值,也可能不是。因此,此调用的效果将不可预测。