poll和select一样,管理多个描写叙述符也是进行轮询,依据描写叙述符的状态进行处理,可是poll没有最大文件描写叙述符数量的限制,select is 1024/2048

#include "stdio.h"
#include "stdlib.h"
#include "sys/socket.h"
#include "netinet/in.h"
#include "netinet/tcp.h"
#include "arpa/inet.h"
#include "string.h"
#include <errno.h>
#include "sys/time.h"
#include "sys/times.h"
#include <unistd.h>
#include "sys/types.h"
#include "poll.h"
#include "sys/stropts.h"
#include <signal.h>
#include <time.h> #define OPEN_MAX 1024
#define MAXLINE 1024 int serverfd,clientfd;
int bindlisten();
int clientconn();
void closemap(int sockfd,int i);
void writeproxy(int i,int n);
int a[65535]={0},b[65535]={0};
char line[MAXLINE]={0};
struct pollfd client[OPEN_MAX];
int maxi;
int
main (int argc ,char **argv) {
int i,listenfd,connfd,sockfd;
int nready;
ssize_t n;
socklen_t clilen;
struct sockaddr_in cliaddr;
int timeout = 1000;
int on; signal (SIGPIPE,SIG_IGN); listenfd=bindlisten();
if (listenfd==-1) {
printf("line46:bind & listen fail\n");
return -1 ;
} client[0].fd=listenfd;
client[0].events=POLLIN; for (i=1;i<OPEN_MAX;i++)
client[i].fd=-1;
maxi=0;//max index into client[] array for ( ; ; ) {
nready=poll(client,maxi+1,timeout);
if (client[0].revents & POLLIN) { //new client connection
clilen=sizeof(cliaddr);
connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&clilen); if (connfd>0) {
printf("Accept a new connection:connfd=%d\n",connfd);
for(i=1;i<OPEN_MAX;i++)
if(client[i].fd<0) {
client[i].fd=connfd;//save descriptor
printf("line68:i=%d,client[i].fd=%d\n",i,client[i].fd);
break;
}
if (i==OPEN_MAX)
perror("too many clients");
client[i].events=POLLIN;
if(i>maxi)
maxi=i; //max index in client[] array clientfd=clientconn();
if (clientfd==-1) {
printf("line98:clientfd fail\n");
return -1;
}
printf("create a new connect to default proxy: %d\n", clientfd); for(i=1;i<OPEN_MAX;i++)
if(client[i].fd<0) {
client[i].fd=clientfd;//save descriptor
printf("line55:i=%d,client[%d].fd=%d\n",i,i,client[i].fd);
break;
}
if (i==OPEN_MAX)
perror("too many clients");
printf("line93:i=%d,nready=%d\n",i,nready);
client[i].events=POLLIN; if(i>maxi)
maxi=i; //max index in client[] array
//map user and default proxy socket
//a keep default proxy,b keep user
a[connfd]=clientfd;
b[clientfd]=connfd; } else
perror("accept");
if (--nready<=0)
continue; //no more readable descriptors
} for (i=1;i<=maxi;i++) {
sockfd=client[i].fd;
if(sockfd<0)
continue;
if (client[i].revents &(POLLIN | POLLERR)) {
printf("line116:i=%d;fd=%d\n",i,client[i].fd);
memset(line,0x00,MAXLINE);
printf("line117:sockfd=%d;nready=%d\n",sockfd,nready);
if((n=read(sockfd,line,MAXLINE)) <=0) {
if (errno==EINTR) {
//don;t remove the socket
continue;
} else {
closemap(sockfd,i);
}
} else
writeproxy(i,n); if (--nready<0)
break; //no more readable descriptors
}
}
}
} int bindlisten() {
struct sockaddr_in tcpaddr;
struct in_addr intfIpAddr;
int tcpaddr_len;
int sockfd;
int client;
int port=8888;
int bReuseaddr=1;
int retVal;
int ret;
int buf,optlen;
int on,errno; memset( &tcpaddr, 0, sizeof(tcpaddr) ); if ( (sockfd= socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
printf ("socket create fail\n");
return -1;
}
// intitalize to hold given restrictions
tcpaddr.sin_family = AF_INET;
tcpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
tcpaddr.sin_port = htons(port); tcpaddr_len = sizeof(tcpaddr); on=1;
errno=0;
if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(char *)(&on),sizeof(on))<0)
{
printf("so_resueadd failed,error %d:%s\n",errno,strerror(errno));
return -2;
} // make bind call
if ((retVal = bind(sockfd, (struct sockaddr *)(&tcpaddr), sizeof(tcpaddr)))< 0 )
{
printf("bind() call failed. Error: %d, %s,port: %d\n ", errno, ( strerror(errno) ), port);
} //listen have 5 queue
if (listen(sockfd, 5) < 0 )
{
printf("Error: Listen socket returned %d %s\n", errno, strerror(errno) );
return -1;
}
return sockfd;
} int clientconn() {
struct sockaddr_in tcpaddr;
char ipHost[10]={0};
int ipPort=8000;
int ret;
int sockfd;
int bReuseaddr=1; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("socket create fail\n");
return -1;
}
printf("line202:sockfd=%d\n",sockfd);
/* Connect to the socket */
memset(&tcpaddr, 0, sizeof(tcpaddr));
//135.245.1.1 is default default proxy proxy ip
strcpy(ipHost, "135.245.1.1");
/* local host, processes must be running on the same machine ... */
/* intitalize to given address */
tcpaddr.sin_family = AF_INET;
tcpaddr.sin_addr.s_addr = inet_addr((const char *)ipHost);
tcpaddr.sin_port = htons(ipPort);
printf("line212:sockfd=%d\n",sockfd);
//basic connect is block, after timeout it return fail
if ((ret = connect(sockfd,(struct sockaddr *)(&tcpaddr),sizeof(tcpaddr))) < 0 ) {
printf("connect fail,retVal=%d,%s\n",errno,strerror(errno));
return 1;
}
return sockfd; } void writeproxy(int i,int n) {
int fdmap;
int ret;
int fd; fd=client[i].fd; if (a[fd]!=0) {
fdmap=a[fd];
// if is in a, it come from default proxy,so write to user
//forward message to ;ucent
printf("Write 1:from %d to %d\n",fd, fdmap);
ret=write(fdmap,line,n);
if (ret <=0) {
if (errno!=EINTR)
closemap(fdmap,i);
} else
printf("write to default proxy\n"); } else if (b[fd]!=0) {
fdmap=b[fd];
//is in b, it come from user
//forward message to user
printf("Write 2 from %d to %d\n",fd, fdmap);
ret=write(fdmap,line,n); if (ret <=0) {
if (errno!=EINTR)
closemap(fdmap,i);
} else
printf("write to user\n");
}
} void closemap (int fd,int i) {
int temp;
int j;
//The socket is wrong or closed.
close(fd);
client[i].fd=-1;
printf("line260 :close %d\n",fd);
//remove the socketfd
//don;t judge from user or default proxy ,set all kind to 0
//one sockfd close ,peer sockfd close
if (a[fd]!=0) {
temp=a[fd];
close (a[fd]);
printf("client close %d\n",a[fd]);
a[fd]=0;
b[temp]=0;
} else if (b[fd]!=0) {
temp=b[fd];
close(b[fd]);
printf("server close %d\n",b[fd]);
b[fd]=0;
a[temp]=0;
} for (j=1;j<=maxi;j++)
if (client[j].fd==temp)
{
client[j].fd=-1;
break;
}
}

最新文章

  1. [LintCode] Reverse Linked List 倒置链表
  2. [TypeScript] TypeScript对象转JSON字符串范例
  3. 缓存算法之belady现象
  4. 黄聪:WordPress 的 Hook 机制与原理(add_action、add_filter)
  5. HBase的安装与使用
  6. 将CMD内的显示内容输出到txt文件
  7. MergeSort 归并排序
  8. android学习--视图列表(ListView和ListActivity)
  9. linux内核编译环境配置
  10. (转)Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)
  11. maven多模块项目构建
  12. c++——数据结构
  13. elk日志平台搭建小记
  14. 【Spring】2、BeanFactory 和FactoryBean的区别
  15. SOA及分布式
  16. matlab下使用svmlib工具包
  17. [linux]linux调度策略对io的影响
  18. win7兼容visual studio 2005 的方法
  19. 第三讲_图像特征与描述Image Feature Descriptor
  20. ubuntu 14.04上源码编译安装php7

热门文章

  1. C#WIFI搜索与连接
  2. 监控iis计数器
  3. http响应的封装
  4. MySQL高可用系列之MHA(二)
  5. hdu 1722 Cake 数学yy
  6. linux 命令 xxd
  7. 研读:AirBag Boosting Smartphone Resistance to Malware Infection
  8. java中的输入输出&lt;1&gt;
  9. (转载) 百度地图工具类封装(包括定位,附近、城市、范围poi检索,反地理编码)
  10. jQuery学习(五)——使用JQ完成复选框的全选和全不选