Skip to content

Instantly share code, notes, and snippets.

@nishidy
Last active August 29, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nishidy/0c8f637713d388a931bb to your computer and use it in GitHub Desktop.
Save nishidy/0c8f637713d388a931bb to your computer and use it in GitHub Desktop.
select (Blocking I/O)
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#define CONCURRENT 10
int main(){
int listen_sock, conn_sock;
struct sockaddr_in server;
struct sockaddr_in client;
fd_set fds, _fds;
char rbuf[65535];
char sbuf[] = "Done.";
typedef struct {
int sock_cnt;
int sock_array[CONCURRENT];
} conn_t;
conn_t conn = { 0, {0} };
listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if( listen_sock == -1 ){
fprintf(stderr, "socket() error [%d].", errno);
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(11111);
if( bind(listen_sock, (struct sockaddr *)&server, sizeof(server)) == -1 ){
fprintf(stderr, "bind() error [%d].", errno);
return -1;
}
if( listen(listen_sock, CONCURRENT) == -1 ){
fprintf(stderr, "listen() error [%d].", errno);
return -1;
}
FD_ZERO(&fds);
FD_SET(listen_sock, &fds);
int cnt=0;
while(1){
memcpy(&_fds, &fds, sizeof(fd_set));
printf("Wait at select #%d.\n", cnt);
int sock_max = listen_sock;
for( int i=0; i<conn.sock_cnt; i++){
printf("%d,",conn.sock_array[i]);
sock_max = conn.sock_array[i]>sock_max?conn.sock_array[i]:sock_max;
}
printf("%d\n",listen_sock);
if( select(sock_max+1, &_fds, NULL, NULL, NULL) == -1 ){
fprintf(stderr,"select error [%d].", errno);
return -1;
}
int len, size;
if(FD_ISSET(listen_sock,&_fds)){
printf("Connect request received.\n");
len = sizeof(client);
conn_sock = accept(listen_sock, (struct sockaddr *)&client, (socklen_t *)&len);
if( conn_sock == -1 ){
fprintf(stderr, "accept error [%d].", errno);
return -1;
}
conn.sock_array[conn.sock_cnt] = conn_sock;
conn.sock_cnt++;
FD_SET(conn_sock,&fds);
}else{
printf("Send request received.\n");
for(int i=0; i<conn.sock_cnt; i++){
if(FD_ISSET(conn.sock_array[i],&_fds)){
printf("Send client is %d.\n",conn.sock_array[i]);
memset(rbuf, 0, sizeof(rbuf));
size = recv(conn.sock_array[i], rbuf, sizeof(rbuf), 0);
printf("Received data size %d byte.\n",size);
if( size == -1){
fprintf(stderr, "recv error [%d].", errno);
return -1;
}else if( size == 0 ){
printf("Closed by %d.\n",conn.sock_array[i]);
shutdown(conn.sock_array[i], 2);
FD_CLR(conn.sock_array[i],&fds);
for(int j=i; j<conn.sock_cnt-1; j++){
conn.sock_array[j] = conn.sock_array[j+1];
}
conn.sock_cnt--;
}else{
printf("%s\n", rbuf);
send(conn.sock_array[i], sbuf, sizeof(sbuf), 0);
}
}
}
}
sleep(1);
cnt++;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment