每个客户端的TCP服务器设置超时

时间:2016-11-02 19:07:20

标签: c++ tcp server connection connection-timeout

我正在使用此代码:

int main(int argc , char *argv[]) {
int device, step=0;
bool writeFuse = false;

int max_clients=CLIENTS;
int opt=TRUE;
int master_socket, activity, new_socket, valread, max_sd;

struct timeval timeout;
    timeout.tv_sec = 3;
    timeout.tv_usec = 0;

//set of socket descriptors
fd_set readfds;

//initialise all client_socket[] to 0 so not checked
for(int i=0; i<max_clients; i++) {
    client_socket[i] = 0;
}

//create a master socket
if((master_socket = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
    perror("ERROR - Socket creation failed");
    exit(EXIT_FAILURE);
}
else cout << "OK - Socket created." << endl;

//set master socket to allow multiple connections , this is just a good habit, it will work without this
if(setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ) {
    perror("ERROR - Socket initialization failed");
    exit(EXIT_FAILURE);
}
else cout << "OK - Socket initializated." << endl;

//type of socket created
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );

//bind the socket to localhost port
if(bind(master_socket, (struct sockaddr *)&address, sizeof(address))<0) {
    perror("ERROR - Bind failed");
    exit(EXIT_FAILURE);
}
else cout << "OK - Bind successful." << endl;

cout << "Listening on port " << PORT << ":" << endl << endl;

//try to specify maximum of 3 pending connections for the master socket
if(listen(master_socket, 3) < 0) {
    perror("listen");
    exit(EXIT_FAILURE);
}

//accept the incoming connection
addrlen = sizeof(address);

while (TRUE) {
    //clear the socket set
    FD_ZERO(&readfds);

    //add master socket to set
    FD_SET(master_socket, &readfds);
    max_sd = master_socket;

    //add child sockets to set
    for(int i=0; i<max_clients ; i++) {
        //socket descriptor
        int sd = client_socket[i];

        //if valid socket descriptor then add to read list
        if(sd > 0)
            FD_SET( sd , &readfds);

        //highest file descriptor number, need it for the select function
        if(sd > max_sd)
            max_sd = sd;
    }

    //wait for an activity on one of the sockets , timeout is NULL , so wait indefinitely
    activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);

    if((activity < 0) && (errno!=EINTR))
        cout << "ERROR - Selection error." << endl;

    //if something happened on the master socket , then its an incoming connection
    if(FD_ISSET(master_socket, &readfds)) {
        if((new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) {
            perror("accept");
            exit(EXIT_FAILURE);
        }

        //inform user of socket number - used in send and receive commands
        cout << "New connection accepted. Socket fd: " << new_socket << ", ip: " << inet_ntoa(address.sin_addr) << ", port: " << ntohs(address.sin_port) << "." << endl;

        //add new socket to array of sockets
        for(int i = 0; i<max_clients; i++) {
            //if position is empty
            if(client_socket[i] == 0) {
                client_socket[i] = new_socket;
                cout << "Adding to list of sockets as " << i << "." << endl;
                client_status[i] = false;

                int sum=0;
                for(int j=0; j<CLIENTS; j++)
                    sum += client_socket[j];
                if(sum == new_socket)
                    message_done(i);

                break;
            }
        }
    }

    //else its some IO operation on some other socket :)
    for(int i=0; i<max_clients; i++) {
        int sd = client_socket[i];

        if(FD_ISSET(sd, &readfds)) {
            //check if it was for closing, and also read the incoming message
            if((valread = read(sd, buffer, 1024)) == 0) {
                //somebody disconnected, process it
                disconnection(sd, i);
            }

            //everything is ok, can process data
            else {
                //set the string terminating NULL byte on the end of the data read
                if(buffer[valread] != '\0')
                    buffer[valread] = '\0';
                int data = atoi(buffer);
                cout << "Client " << i << " send message: " << data << endl;

                //some data processing stuff
            }
        }
    }
}

return 0;
}

这是一个具有多个连接的简单TCP服务器。我正在尝试为每个连接的客户端设置接收超时。我一直在通过互联网搜索,并做了很少的尝试。但没有成功。

1 个答案:

答案 0 :(得分:0)

您使用! (@IsMember("[Supervisor]": "[Admin]" ; @UserRoles)); 选项致电setsockopt()