server:
/*
* Pollserver.c
*
* Created on: 2012-9-9
* Author: sangerhoo
*/
#include<sys/types.h>
#include<ctype.h>
#include<strings.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<ctype.h>
#include<errno.h>
#include<sys/time.h>
#include<stdio.h>
#include<string.h>
#include<sys/poll.h>
#include<stdlib.h>
#define LISTEN_QUEUE_NUM 5
#define MAX_CONNECT 1024
#define BUFFER_SIZE 256
#define ECHO_PORT 2029
static struct pollfd clipoll[MAX_CONNECT];
int max = 0;
/*initialize poll struct*/
static void poll_init()
{
int i;
for (i = 0; i < MAX_CONNECT; i++)
clipoll[i].fd = -1;
}
/*
find a unused pollfd struct
if found then return its index
else return -1
*/
static int poll_alloc()
{
int i;
for (i = 0; i < MAX_CONNECT; i++)
{
if (clipoll[i].fd < 0)
return i;
}
return -1;
}
/*find used max index in pllfd*/
static void update_max()
{
int i;
max = 0;
for (i = 0; i < MAX_CONNECT; i++)
{
if (clipoll[i].fd > 0)
max = i;
}
}
/*free a pollfd when unused*/
static int poll_free(int i)
{
close(clipoll[i].fd);
clipoll[i].fd = -1;
clipoll[i].events = 0;
clipoll[i].revents = 0;
update_max();
}
/*
fill up pollfd with file descriptable
and event
*/
static int poll_set_item(int fd, uint32_t events)
{
int i;
if ((i = poll_alloc()) < 0)
return -1;
clipoll[i].fd = fd;
clipoll[i].events = events;
clipoll[i].revents = 0;
if (i > max)
max = i;
return 0;
}
int main(int argc, char **argv)
{
struct sockaddr_in servaddr, remote;
int request_sock, new_sock;
int nfound, i, bytesread;
uint32_t addrlen;
char buf[BUFFER_SIZE];
/*setup socket*/
if ((request_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket");
return -1;
}
/*fill up ip address structure*/
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(ECHO_PORT);
/*bind server ip address structure*/
if (bind(request_sock, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
{
perror("bind");
return -1;
}
/*listen client*/
if (listen(request_sock, LISTEN_QUEUE_NUM) < 0)
{
perror("listen");
return -1;
}
poll_init();
poll_set_item(request_sock, POLLIN);
while (1)
{
/*check whether ready file exist ?*/
if ((nfound = poll(clipoll, max + 1, 500)) < 0)
{
if (errno == EINTR)
{
printf("interruptedb system call\n");
continue;
}
perror("poll");
return -1;
}else if(nfound == 0)
{
printf(".");
fflush(stdout);
continue;
}
/*check listen socket if ready or not ?*/
if (clipoll[0].revents & (POLLIN | POLLERR))
{
addrlen = sizeof(remote);
if ((new_sock = accept(request_sock, (struct sockaddr *) &remote, &addrlen)) < 0)
{
perror("accept");
return -1;
}
printf("connection fromm host %s,port %d, socket %d\r\n",
inet_ntoa(remote.sin_addr), ntohs(remote.sin_port), new_sock);
if (poll_set_item(new_sock, POLLIN) < 0)
fprintf(stderr, "Too many connects\r\n");
nfound--;
}
/*check communicating socket if ready or not ? */
for (i = 1; i <= max && nfound > 0; i++)
{
if (clipoll[i].fd >= 0 && clipoll[i].revents & (POLLIN | POLLERR))
{
nfound--;
if((bytesread = read(clipoll[i].fd, buf, sizeof(buf) - 1)) < 0)
{
perror("read");
poll_free(i);
continue;
}
if(bytesread == 0)
{
fprintf(stderr, "server: end of file on %d\r\n", clipoll[i].fd);
poll_free(i);
continue;
}
buf[bytesread] = 0;
printf("%s:%d bytes from %d :%s\n", argv[0], bytesread,
clipoll[i].fd, buf);
if (write(clipoll[i].fd, buf, bytesread) != bytesread)
{
perror("echo");
poll_free(i);
continue;
}
}
}
}
return 0;
}
client:
/*
* pollclient.c
*
* Created on: 2012-9-9
* Author: sangerhoo
*/
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<netinet/in.h>
#include<errno.h>
#include<ctype.h>
#include<netdb.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/select.h>
#include<sys/poll.h>
#define RET_OK 0
#define RET_ERR -1
#define LISTEN_QUEUE_NUM 5
#define BUFFER_SIZE 256
#define ECHO_PORT 2029
int main(int argc, char **argv)
{
int sock;
struct sockaddr_in servaddr;
struct hostent *server;
static struct pollfd cpoll[2];
int nfound, bytesread;
char buf[BUFFER_SIZE];
if(argc < 2)
{
fprintf(stderr, "usage %s hostname\n", argv[0]);
return RET_ERR;
}
if((server = gethostbyname(argv[1])) == NULL)
{
perror("gethostbyname. ");
return RET_ERR;
}
/*setup socket*/
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket");
return -1;
}
/*fillup ip address structure*/
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = *(uint32_t *) server->h_addr;
servaddr.sin_port = htons((uint16_t) ECHO_PORT);
/*connect to server*/
if(connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
{
perror("connect");
return -1;
}
/*fill up poll struct*/
cpoll[0].fd = fileno(stdin);
cpoll[0].events = POLLIN;
cpoll[1].fd = sock;
cpoll[1].events = POLLIN;
while (1)
{
if ((nfound = poll(cpoll, 2, -1)) < 0)
{
if (errno == EINTR)
{
fprintf(stderr, "interruptedb system call\n");
continue;
}
perror("select");
exit(1);
}
/*check stdin is ready or not ? */
if (cpoll[0].revents & (POLLIN | POLLERR))
{
if(fgets(buf, sizeof(buf), stdin) == NULL)
{
if (ferror(stdin))
{
perror("stdin");
return -1;
}
return 0;
}
/*write to socket*/
if (write(sock, buf, strlen(buf)) < 0)
{
perror("write");
return -1;
}
}
/*check socket is ready or not ? */
if(cpoll[1].revents & (POLLIN | POLLERR))
{
/*read from socket*/
if((bytesread = read(sock, buf, sizeof(buf))) < 0)
{
perror("read");
exit(1);
}else if(bytesread == 0)
{
fprintf(stderr, "server disconnect\n");
exit(0);
}
buf[bytesread] = 0;
printf("%s\n", buf);
}
}
return 0;
}
运行结果是:
root@hdp3:/media/sf_workspace/sangerhoo/unp# ..../................................................................................connection fromm host 127.0.0.1,port 53105, socket 4
.....................
root@hdp3:/media/sf_workspace/sangerhoo/unp# ............/pollserver:4 bytes from 4 :dfd
..../pollserver:4 bytes from 4 :fdf
...../pollserver:10 bytes from 4 :sangerhoo
..../pollserver:6 bytes from 4 :sd
......../pollserver:6 bytes from 4 :hello
-------------------client----------------------
dfd
dfd
fdf
fdf
sangerhoo
sangerhoo
sd^H^H^H
sd
hello
hello
...............................................................................................................................................................................................................................................................................................................................................................................................................................................................