Skip to content

Instantly share code, notes, and snippets.

@oza
Created December 22, 2009 10:38
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 oza/261661 to your computer and use it in GitHub Desktop.
Save oza/261661 to your computer and use it in GitHub Desktop.
-- Project name --
hello server
-- Description --
hello server is a simple server which say "hello" when clients connected.
These codes are suitable to understand poll and select system call.
-- How to build --
Please type ($ is a prompt)
$ make
and you will see binary "poll" and "select".
$ ./poll
or
$ ./select
and hello server is going to run and listen at port 12345.
Run new terminal and type
$ telnet localhost 12345
to confirm it's listening 12345 port. You can also run new
client in another terminal.
all:
make poll
make select
poll: poll.c
gcc poll.c -o poll
select:select.c
gcc select.c -o select
clean:
rm poll
rm select
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#define LISTENQ 1
#define MAX_CONNECTION 10
#define PORT_NO 12345
#define HELLO_STRING "hello\n"
int main()
{
int listen_fd = 0;
int conn_fd = 0;
int nonblk_conn_fd = 0;
int client_fd = 0;
int default_flag = 0;
int nonblk_flag = 0;
int maxi = 0;
int nready = 0;
int i = 0;
struct sockaddr_in addr;
struct pollfd client[MAX_CONNECTION];
// open socket and bind and listen it.
listen_fd = socket(AF_INET,SOCK_STREAM,0);
//fcntl(listen_fd,F_SETFL,O_NONBLOCK);
memset( &addr, 0, sizeof(addr) );
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(PORT_NO);
bind( listen_fd, &addr, sizeof(addr) );
listen( listen_fd, LISTENQ );
client[0].fd = listen_fd;
client[0].events = POLLIN | POLLOUT;
for( i = 1 ; i < MAX_CONNECTION ; ++i ){
client[i].fd = -1;
}
while(1){
nready = poll( client, maxi+1 , 10 );
if( client[0].revents & ( POLLIN | POLLOUT ) ){
// block accept.
conn_fd = accept( listen_fd, NULL, NULL );
printf("accepted.\n");
default_flag = fcntl(conn_fd,F_GETFL);
nonblk_flag = fcntl(conn_fd,F_SETFL,O_NONBLOCK);
// poll 用の配列の管理.
for( i = 1 ; i < MAX_CONNECTION ; ++i ){
if( client[i].fd < 0 ){
client[i].fd = conn_fd;
printf("conn_fd registered.\n");
break;
}
}
if( i == MAX_CONNECTION ){
printf("exceeded.\n");
}
if( i > maxi ){
maxi = i;
client_fd = client[i].fd;
write( client_fd, HELLO_STRING, sizeof(HELLO_STRING));
printf("wrote.\n");
//fcntl(client_fd,F_SETFL,default_flag);
read( client_fd, NULL, 5);
printf("read.\n");
// This program doesn't close...
//close( client_fd );
//printf("closed.\n");
//client[i].fd = -1;
}
if( -nready < 0 )
continue;
}
}
return 0;
}
#include <stdio.h> /* printf() */
#include <sys/socket.h> /* socket() */
#include <sys/types.h> /* */
#include <netinet/in.h> /* sockaddr_in */
#include <unistd.h> /* write() */
#include <fcntl.h>
#define PORT_NO 12345
#define LISTENQ 5
#define HELLO_STRING "hello!\n"
#define MAX_CONNECTION 10
int main()
{
int listen_fd = 0;
int conn_fd = 0;
struct sockaddr_in sock;
int default_flag = 0;
int nonblock_flag = 0;
int max_fds = 0;
int client[MAX_CONNECTION];
int nready = 0;
int maxi = 0;
int i = 0;
fd_set read_fds, default_read_fds;
printf("init socket.\n");
listen_fd = socket( AF_INET, SOCK_STREAM, 0 );
sock.sin_family = AF_INET;
sock.sin_addr.s_addr = INADDR_ANY;
sock.sin_port = htons(PORT_NO);
bind( listen_fd, &sock, sizeof(sock) );
listen( listen_fd, LISTENQ );
/* init select */
FD_ZERO( &default_read_fds );
FD_SET( listen_fd, &default_read_fds );
max_fds = listen_fd + 1;
maxi = -1;
/* init client descriptor */
for( i = 0 ; i < MAX_CONNECTION ; ++i ){
client[i] = -1;
}
while(1){
read_fds = default_read_fds;
printf("start to select.\n");
nready = select( max_fds, &read_fds, NULL, NULL, NULL );
if( FD_ISSET( listen_fd, &read_fds) ){
/* new connection is coming ! */
FD_CLR( listen_fd, &read_fds );
#ifdef FD_COPY
/**
* Note:
* If there is a copy interface ( FD_COPY ) in your compile
* environment, it's better to use that.
*
* usage:
* FD_COPY( src, dest );
*
* Thx, frsyuki(http://github.com/frsyuki)!
*/
FD_COPY(&default_read_fds,&read_fds);
#else
read_fds = default_read_fds;
#endif
printf("start to accept.\n");
conn_fd = accept( listen_fd, NULL, NULL );
/* manage multipul io descriptor. */
for( i = 0 ; i < MAX_CONNECTION ; ++i ){
if( client[i] < 0 ){
client[i] = conn_fd;
printf("conn_fd registered.\n");
break;
}
}
if( i == MAX_CONNECTION ){
printf("exceeded.\n");
continue;
}
if( i > maxi ){
maxi = i;
client[i] = conn_fd;
write( conn_fd, HELLO_STRING, sizeof(HELLO_STRING) );
printf("wrote.\n");
// FD_SET( conn_fd, &default_read_fds );
/* This program doesn't close... */
//close( client_fd );
//printf("closed.\n");
//client[i].fd = -1;
}
}
}
// never come here.
close(listen_fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment