【问题标题】:C Accept Client Socket "Invalid Argument" Error when adding Signal ThreadC在添加信号线程时接受客户端套接字“无效参数”错误
【发布时间】:2018-12-12 17:26:08
【问题描述】:

我正在为班级做一个项目,但遇到了一个问题。

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

但是,我的服务器->客户端连接现在不再正常工作。我不断得到 -1 作为我的套接字 id,错误是“无效参数”。这对我来说没有任何意义,因为如果我禁用信号线程,一切都会再次正常工作。我把下面的代码贴出来。

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..");
        }

接受时出错..:打印出无效参数。

当我禁用此行时:

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

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

编辑:解决了 ty chris Turner。我在接受的长度 arg 中有错误的字段。奇怪的是它以前是如何工作的!

【问题讨论】:

  • 你在处理信号后得到-1吗?
  • 另外,你在哪里初始化c?在调用accept之前需要将其设置为client的大小
  • 是的,它发生在处理信号之后。而且我想我不会在任何奇怪的地方初始化“c”。但是,如果我禁用信号线程,它为什么会起作用。我会尝试初始化它
  • &c 可能应该是 &length: length = sizeof(struct sockaddr_in);
  • 现在可以使用了,谢谢,我必须将其更改为 &length !!!之前的工作方式真的很奇怪

标签: c sockets networking signals


【解决方案1】:

你从不给c 分配一个合理的值,所以你在这里将随机垃圾传递给accept

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

它可能是也可能不是合法价值。所以这个电话的效果将是不可预测的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-17
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多