Article title: select function example of linuxsocket. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.
The select function can communicate with multiple sockets in a non-blocking manner. The program only demonstrates the use of the select function. the function is very simple. even if a connection is closed, the current number of connections is not modified. when the number of connections reaches the maximum value, the program is terminated.
1. The program uses an array fd_A. after the communication starts, multiple socket descriptors to be communicated are put into this array.
2. generate a socket descriptor named sock_fd for listening to the port.
3. put the descriptor not 0 in sock_fd and array fd_A into the fdsr set to be checked by select.
4. processes connections that can receive data in fdsr. If it is sock_fd, it indicates that a new connection is added, and the socket descriptor of the new connection is placed in fd_A.
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define MYPORT 1234 // the port users will be ING
# Define BACKLOG 5 // how many pending connections queue will hold
# Define BUF_SIZE 200
Int fd_A [BACKLOG]; // accepted connection fd
Int conn_amount; // current connection amount
Void showclient ()
{
Int I;
Printf ("client amount: % d \ n", conn_amount );
For (I = 0; I <BACKLOG; I ++ ){
Printf ("[% d]: % d", I, fd_A [I]);
}
Printf ("\ n ");
}
Int main (void)
{
Int sock_fd, new_fd; // listen on sock_fd, new connection on new_fd
Struct sockaddr_in server_addr; // server address information
Struct sockaddr_in client_addr; // connector's address information
Socklen_t sin_size;
Int yes = 1;
Char buf [BUF_SIZE];
Int ret;
Int I;
If (sock_fd = socket (AF_INET, SOCK_STREAM, 0) =-1 ){
Perror ("socket ");
Exit (1 );
}
If (setsockopt (sock_fd, SOL_SOCKET, SO_REUSEADDR, & yes, sizeof (int) =-1 ){
Perror ("setsockopt ");
Exit (1 );
}
Server_addr.sin_family = AF_INET; // host byte order
Server_addr.sin_port = htons (MYPORT); // short, network byte order
Server_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
Memset (server_addr.sin_zero, '\ 0', sizeof (server_addr.sin_zero ));
If (bind (sock_fd, (struct sockaddr *) & server_addr, sizeof (server_addr) =-1 ){
Perror ("bind ");
Exit (1 );
}
If (listen (sock_fd, BACKLOG) =-1 ){
Perror ("listen ");
Exit (1 );
}
Printf ("listen port % d \ n", MYPORT );
Fd_set fdsr;
Int maxsock;
Struct timeval TV;
Conn_amount = 0;
Sin_size = sizeof (client_addr );
Maxsock = sock_fd;
While (1 ){
// Initialize file descriptor set
FD_ZERO (& fdsr );
FD_SET (sock_fd, & fdsr );
// Timeout setting
TV. TV _sec = 30;
TV. TV _usec = 0;
// Add active connection to fd set
For (I = 0; I <BACKLOG; I ++ ){
If (fd_A [I]! = 0 ){
FD_SET (fd_A [I], & fdsr );
}
}
Ret = select (maxsock + 1, & fdsr, NULL, NULL, & TV );
If (ret <0 ){
Perror ("select ");
Break;
} Else if (ret = 0 ){
Printf ("timeout \ n ");
Continue;
}
// Check every fd in the set
For (I = 0; I <conn_amount; I ++ ){
If (FD_ISSET (fd_A [I], & fdsr )){
Ret = recv (fd_A [I], buf, sizeof (buf), 0 );
If (ret <= 0) {// client close
Printf ("client [% d] close \ n", I );
Close (fd_A [I]);
FD_CLR (fd_A [I], & fdsr );
Fd_A [I] = 0;
} Else {// receive data
If (ret <BUF_SIZE)
Memset (& buf [ret], '\ 0', 1 );
Printf ("client [% d] send: % s \ n", I, buf );
}
}
}
// Check whether a new connection comes
If (FD_ISSET (sock_fd, & fdsr )){
New_fd = accept (sock_fd, (struct sockaddr *) & client_addr, & sin_size );
If (new_fd <= 0 ){
Perror ("accept ");
Continue;
}
// Add to fd queue
If (conn_amount <BACKLOG ){
Fd_A [conn_amount ++] = new_fd;
Printf ("new connection client [% d] % s: % d \ n", conn_amount,
Inet_ntoa (client_addr.sin_addr), ntohs (client_addr.sin_port ));
If (new_fd> maxsock)
Maxsock = new_fd;
}
Else {
Printf ("max connections arrive, exit \ n ");
Send (new_fd, "bye", 4, 0 );
Close (new_fd );
Break;
}
}
Showclient ();
}
// Close other connections
For (I = 0; I <BACKLOG; I ++ ){
If (fd_A [I]! = 0 ){
Close (fd_A [I]);
}
}
Exit (0 );
}