poll
server.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <poll.h>
#include <limits.h>
#include <signal.h>
#define MAX_SIZE 100
#define OPEN_MAX 1024
#define ENOSPACE 1
#define INFTIM -1
struct pollfd client[OPEN_MAX];
void init_pollfd(int listen_fd)
{
int i;
client[0].fd = listen_fd;
client[0].events = POLLRDNORM;
for(i=1;i<OPEN_MAX;i++)
client[i].fd = -1;
}
int add_client(int fd,int *max)
{
int i;
for(i=0;i<OPEN_MAX;i++)
{
if(client[i].fd < 0)
{
client[i].fd = fd;
client[i].events = POLLRDNORM;
if(i > *max )
*max = i;
return 0;
}
}
if(i == OPEN_MAX)
return ENOSPACE;
}
int main()
{
int listen_fd = socket(AF_INET,SOCK_STREAM,0);
if(listen_fd < 0)
perror("listen error");
init_pollfd(listen_fd);
int max_index = 0;
struct sockaddr_in listen_sock;
bzero(&listen_sock,sizeof(listen_sock));
listen_sock.sin_family = AF_INET;
listen_sock.sin_port = htons(12345);
int err = inet_pton(AF_INET,"127.0.0.1",(char *)&listen_sock.sin_addr);
if(err < 0)
perror("inet_pton error");
err = bind(listen_fd,(struct sockaddr *)&listen_sock,sizeof(listen_sock));
if(err < 0)
perror("bind error");
err = listen(listen_fd,5);
if(err < 0)
perror("listen error");
while(1)
{
int nready = poll(client,max_index+1,INFTIM);
if(client[0].revents & POLLRDNORM)
{
struct sockaddr_in client_addr;
int client_addr_len;
int client_fd = accept(listen_fd,(struct sockaddr *)&client_addr,&client_addr_len);
if(errno == EINTR)
continue;
add_client(client_fd,&max_index);
nready--;
if(nready<=0)
continue;
}
int i;
for(i=0;i<OPEN_MAX;i++)
{
char rcv[MAX_SIZE];
if(client[i].fd < 0)
continue;
if(client[i].revents & (POLLRDNORM | POLLERR))
{
int n = read(client[i].fd,rcv,MAX_SIZE);
if(n<0)
{
if(errno == ECONNRESET)
{
close(client[i].fd);
client[i].fd = -1;
}
}
else if(n==0)
{
close(client[i].fd);
client[i].fd = -1;
printf("rcv fin from peer\n");
}
else
{
rcv[n] = '\0';
printf("%s\n",rcv);
write(client[i].fd,rcv,n);
}
nready--;
if(nready <=0)
break;
}
}
}
return 0;
}
client.c
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/select.h>
int max(int a, int b)
{
return a>b?a:b;
}
#define MAX_SIZE 100
void send_echo_fun(int fd)
{
char buf_snd[MAX_SIZE];
char buf_rcv[MAX_SIZE];
int len;
fd_set rset;
FD_ZERO(&rset);
while(1)
{
FD_SET(fileno(stdin),&rset);
FD_SET(fd,&rset);
int maxfd = max(fileno(stdin),fd) + 1;
select(maxfd,&rset,NULL,NULL,NULL);
if(FD_ISSET(fd,&rset))
{
int len = read(fd,buf_rcv,MAX_SIZE);
if(len == 0)
{
printf("rcv fin from peer\n");
printf("tag\n");
return;
}
buf_rcv[len]='\0';
printf("%s\n",buf_rcv);
}
if(FD_ISSET(fileno(stdin),&rset))
{
char *s = fgets(buf_snd,MAX_SIZE,stdin);
if(s == NULL)
break;
int n = strlen(buf_snd)-1;
if(n>0)
{
write(fd,buf_snd,n);
}
}
}
}
int main()
{
int client_fd ;
client_fd = socket(AF_INET,SOCK_STREAM,0);
if(client_fd < 0)
perror("socket error");
struct sockaddr_in server_sock;
server_sock.sin_family = AF_INET;
server_sock.sin_port = htons(12345);
int err = inet_pton(AF_INET,"127.0.0.1",&server_sock.sin_addr);
if(err != 1)
perror("inet_pton error");
err = connect(client_fd,(struct sockaddr *)&server_sock,sizeof(server_sock));
if(err == 0)
printf("connect ok\n");
send_echo_fun(client_fd);
close(client_fd);
return 0;
}