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

TCP server set timeout for each client

本文关键字:设置 超时 时间 客户端 服务器 TCP      更新时间:2023-10-16

我正在使用这个代码:

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] != '')
                    buffer[valread] = '';
                int data = atoi(buffer);
                cout << "Client " << i << " send message: " << data << endl;
                //some data processing stuff
            }
        }
    }
}
return 0;
}

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

您使用SO_RCVTIMEO选项调用setsockopt()