【问题标题】:create socket/thread in a loop在循环中创建套接字/线程
【发布时间】:2014-10-18 11:13:17
【问题描述】:

我正在努力尝试通过 for 循环创建套接字;循环将为每个套接字创建一个线程。

这是我当前运行良好的代码:

输入; ./client1 2344./client1 2343。 (2344 和 2343 是端口)。

处理套接字,每个都有一个线程:

    struct sockaddr_in serv; /* socket info about our server */
    struct sockaddr_in serv2; /* socket info about our server */
    int mysocket;            /* socket used to listen for incoming connections */
    int mysocket2;

    memset(&serv, 0, sizeof(serv));           /* zero the struct before filling the fields */
    serv.sin_family = AF_INET;                /* set the type of connection to TCP/IP */
    serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
    serv.sin_port = htons(PORTNUM);          
    memset(&serv2, 0, sizeof(serv2));           /* zero the struct before filling the fields */
    serv2.sin_family = AF_INET;                /* set the type of connection to TCP/IP */
    serv2.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
    serv2.sin_port = htons(PORTNUM2);           /* set the server port number */
    // see http://stackoverflow.com/questions/15976137/local-host-server-socket-program-not-working

    mysocket = socket(AF_INET, SOCK_STREAM, 0);    
    mysocket2 = socket(AF_INET, SOCK_STREAM, 0);

    int optVal = 1;
    if (setsockopt(mysocket, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) < 0) {
        perror("Error setting socket option");
        exit(1);
    }    
    if (setsockopt(mysocket2, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) < 0) {
        perror("Error setting socket option");
        exit(1);
    }


    if (bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr_in))){
        perror("Error binding socket to port");
        exit(1);
    }
    if (bind(mysocket2, (struct sockaddr *)&serv2, sizeof(struct sockaddr_in))){
        perror("Error binding socket to port");
        exit(1);
    }
    /* start listening, allowing a queue of up to 1 pending connection */
    listen(mysocket, SOMAXCONN);
    listen(mysocket2, SOMAXCONN);

    pthread_t inc_x_thread1;
    pthread_t inc_x_thread2;

    pthread_create(&inc_x_thread1, NULL, run, &mysocket);
    pthread_create(&inc_x_thread2, NULL, run, &mysocket2);
    pthread_join(inc_x_thread1, NULL);
    pthread_join(inc_x_thread2, NULL);

以下代码是我尝试在 for 循环中重构代码:

    int socketDeckPair = 0;
    int threads = 2; 
    pthread_t* tid[2];
    char* ports[] = {"2343", "2344"};

    //This is where the information about the incoming connection will
    for(;socketDeckPair < 2; socketDeckPair=socketDeckPair+1){
        struct sockaddr_in serv; /* socket info about our server */

        int mysocket;            /* socket used to listen for incoming connections */

        memset(&serv, 0, sizeof(serv));           /* zero the struct before filling the fields */
        serv.sin_family = AF_INET;                /* set the type of connection to TCP/IP */
        serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
        serv.sin_port = htons(atoi(ports[socketDeckPair]));           /* set the server port number */

        mysocket = socket(AF_INET, SOCK_STREAM, 0);

        int optVal = 1;
        if (setsockopt(mysocket, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) < 0) {
            perror("Error setting socket option");
            exit(1);
        }

        if (bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr_in))){
            perror("Error binding socket to port");
            exit(1);
        }

        listen(mysocket, SOMAXCONN);

        pthread_create(&tid[socketDeckPair], NULL, run, &mysocket);
    }
    int i = 0;
    for(; i < threads; i++){
        pthread_join(tid[i], NULL);
    }

现在如果我尝试运行./client1 2344,我会得到奇怪的结果。每次我运行 ./client1 时,线程 id 的备用:

f77fe700
f6dfd700
f77fe700
f6dfd700
f77fe700

我做错了什么?

谢谢 丹尼尔

【问题讨论】:

  • 这个pthread_create(&amp;tid[socketDeckPair] 应该引起编译器警告你,至少所有警告都在:-Wall -Wextra -pedantic(对于 gcc)。认真对待警告是个好主意。
  • 建议不要在线程内创建套接字。实际上,与每个套接字相关的变量正在为每个套接字“重用”而不是唯一的。

标签: c sockets network-programming pthreads


【解决方案1】:
  • 问题一:

    pthread_t* tid[2];
    

    必须是:

    pthread_t tid[2];
    

  • 问题 2:
    for 循环内的以下行中:

    pthread_create(&tid[socketDeckPair], NULL, run, &mysocket);
    

    您正在使用局部变量 mysocket,当代码到达下一个 }(即:下一行)时,该变量超出范围。
    您正在传递变量的地址,该地址在下一个 }

    中已过时

【讨论】:

  • 是的 - 它只是一个句柄/令牌。将其转换并按值传递。
猜你喜欢
  • 2019-05-25
  • 2020-02-22
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多