Created
December 22, 2009 10:38
-
-
Save oza/261661 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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