使用 select() 陷入无限循环

问题描述 投票:0回答:1

这是我在 C 中的套接字 API 的主要函数。它打印

starts loop
,例如,当我输入
join 087 01
时,程序不执行任何操作。我已经测试了在单独的文件中处理输入命令行的代码并且工作正常。

#include <netdb.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <time.h>
//#include "networkstructure.h"
#include "udp.h"
#include "tcp.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_ARGS 5 // Maximum number of arguments for a command

int main(int argc, char* argv[])
{
    char serverIP_backup[] = "193.136.138.142";
    char serverport_packup[] = "59000";
    
    char IP[50];
    char tcp_port[50];
    char regIP[50];
    char regUDP[50];
    
    strcpy(IP, argv[1]);
    strcpy(tcp_port, argv[2]);
    strcpy(regIP, argv[3]);
    strcpy(regUDP, argv[4]);


    struct app host; //myself
    app* host_ptr = &host;
    struct sockaddr_in self_addr;
    struct addrinfo self_hints; 
    socklen_t self_addrlen = sizeof(self_addr);

    
    struct addrinfo *self_res=NULL;

    //host initialization
    host.connected = 0;
    host.registed = 0;
    strcpy(host.UDPserver_IP, regIP);
    strcpy(host.UDPserver_port, regUDP);
    host.TCPsocket_next = -1;
    host.TCPsocket_prev = -1;
    host.TCPincoming = -1;
    host.TCPcord = -1;
    host.fw_table = NULL;
    strcpy(host.self.IP, IP);
    strcpy(host.self.TCP_port, tcp_port);
    host.UDPsocket = UDPconnect(regIP, regUDP);
    struct timeval timeout; //timemout for infinite while loop
    timeout.tv_sec = 60; //while loop will run for 1 minute
    timeout.tv_usec = 0;
    memset(&self_hints, 0, sizeof (self_hints));
    self_hints.ai_family = AF_INET;
    self_hints.ai_flags = SOCK_STREAM;
    if (getaddrinfo(host.self.IP,host.self.TCP_port,&self_hints,&self_res) == -1)
    {
        printf("ERROR: obtaining self addr info not unsuccsseful\n");
        exit(EXIT_FAILURE);
    }

    int maxfd = 0;
    int counter = 0;
    printf("program starts\n");

    while(1) //main loop
    {


            FD_ZERO(&(host. rfds)); //clears fd_set
            FD_SET(0, &(host.rfds)); //stdin (keyboard)
            FD_SET(host.UDPsocket, &(host.rfds)); //socket for UDP conection with server
            FD_SET(host.TCPcord, &(host.rfds)); //incoming cord connection socket
            FD_SET(host.TCPincoming, &(host.rfds)); //incoming outsider node connection socket
            maxfd= host.TCPincoming;

            if (host.TCPcord != -1)
            {
                FD_SET(host.TCPcord, &(host.rfds));
                if(host.TCPcord > maxfd)maxfd=host.TCPcord;
            }

            if (host.TCPincoming != -1)
            {
                FD_SET(host.TCPincoming, &(host.rfds));
                if(host.TCPincoming > maxfd)maxfd=host.TCPincoming;
            }

            if (host.TCPsocket_next != -1)
            {
                FD_SET(host.TCPsocket_next, &(host.rfds));
                if(host.TCPsocket_next > maxfd)maxfd=host.TCPsocket_next;
            }
                
            printf("starts loop\n");
            counter = select (maxfd + 1, &(host.rfds), (fd_set *) NULL, (fd_set *) NULL, &timeout);

            if (counter > 0) //1 or more sockets are ready to be operated upon
            {
                
                if(FD_ISSET(0, &(host.rfds)))
                {
                    printf("starts reading buffer\n");
                    char buffer[300];
                    memset(buffer, 0, 300);
                    fgets(buffer, strlen(buffer), stdin);
                    
                    int n = 0;
                    char* token[5];
                    token[n]=strtok(buffer, " \n");
                    while(token[n]!=NULL && n<5)
                    {
                        n++;
                        token[n] = strtok(NULL, " \n");
                    }

                    for (int i = 0; i<n; i++)
                    {
                        token[i][strcspn(token[i], "\n")] = '\0';
                        printf("\ninput token: %s\n", token[i]);
                    }
                        


                    if ((strcmp(token[0], "join") == 0) || (strcmp(token[0], "j") == 0))

                    {
                        
                        if (host.connected) 
                        {
                            printf("you are already registed\n");
                            exit(0);
                        }
                        printf("input command: join\n");
                        join(host_ptr, token[1], token[2]);

                    
                    }
                    else if ((strcmp(token[0], "exit") == 0) || strcmp(token[0], "x") == 0)
                    {
                        printf("Exit command. exiting...");
                        exit(EXIT_SUCCESS);
                    }
                }

                if(FD_ISSET(host.TCPincoming, &(host.rfds)))
                {
                    host.TCPincoming = newTCPserver(host.self.IP, host.self.TCP_port); //now listening to external connection requests
                    inbound_connection(host_ptr);

                    
                }
                 if(FD_ISSET(host.TCPsocket_next, &(host.rfds)))
                {
                    //aqui sou o nó l
                    msg_from_next(host_ptr);
                }
            }

    }
}

    return 0;
c sockets posix-select
1个回答
2
投票

至少这个麻烦

fgets()
什么也没读

char buffer[300];
memset(buffer, 0, 300);
fgets(buffer, strlen(buffer), stdin);  // strlen(buffer)??, that is 0!

// Suggest
fgets(buffer, sizeof buffer, stdin);

// Even better, check `fgets()` return value.  
// No need for `memset(buffer, 0, 300);`.
© www.soinside.com 2019 - 2024. All rights reserved.