062. //绑定地址
063. if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0 )
064. {
065. printf("IPaddress bound failure!\n");
066. exit(1);
067. }
068.
069. //开始监听
070. listen(listenfd, LISTENQ);
071.
072. client[0].fd = listenfd; /*将数组中的第一个元素设置成监听描述字*/
073.
074. client[0].events = POLLIN; /*将测试条件设置成普通或优先级带数据可读,此处书中为POLLRDNORM,
075. 但是怎么也编译不过去 ,编译器就是找不到,所以就临时改成了POLLIN这个条件,
076. 希望以后能弄清楚。
077. */
078.
079. for(i = 1;i < OPEN_MAX; ++i) /*数组中的其它元素将暂时设置成不可用*/
080. client[i].fd = -1;
081. maxi = 0;
082.
083. while(1)
084. {
085. nready = poll(client, maxi+1,INFTIM); //将进程阻塞在poll上
086. if( client[0].revents & POLLIN/*POLLRDNORM*/ ) /*先测试监听描述字*/
087. {
088. connfd = accept(listenfd,(struct sockaddr*)&servaddr, &clilen);
089. for(i = 1; i < OPEN_MAX; ++i)
090. if( client[i].fd < 0 )
091. {
092. client[i].fd = connfd; /*将新连接加入到测试数组中*/
093. client[i].events = POLLIN;//POLLRDNORM; /*测试条件普通数据可读*/
094. break;
095. }
096. if( i == OPEN_MAX )
097. {
098. printf("too many clients"); //连接的客户端太多了,都达到最大值了
099. exit(1);
100. }
101.
102. if( i > maxi )
103. maxi = i; //maxi记录的是数组元素的个数
104.
105. if( --nready <= 0 )
106. continue; //如果没有可读的描述符了,就重新监听连接
107. }
108.
109. for(i = 1; i <= maxi; i++) /*测试除监听描述字以后的其它连接描述字*/
110. {
111. if( (sockfd = client[i].fd) < 0) /*如果当前描述字不可用,就测试下一个*/
112. continue;
113.
114. if(client[i].revents & (POLLIN/*POLLRDNORM*/ | POLLERR))/*如果当前描述字返回的是普通数据可读或出错条件*/
115. {
116. if( (n = read(sockfd, buf, MAXLINE)) < 0) //从套接口中读数据
117. {
118. if( errno == ECONNRESET) //如果连接断开,就关闭连接,并设当前描述符不可用
119. {
120. close(sockfd);
121. client[i].fd = -1;
122. }
123. else
124. perror("read error");
125. }
126. else if(n == 0) //如果数据读取完毕,关闭连接,设置当前描述符不可用
127. {
128. close(sockfd);
129. client[i].fd = -1;
130. }
131. else
132. write(sockfd, buf, n); //打印数据
133.
134. if(--nready <= 0)
135. break;
136.
137. }
138. }
139. }
140.
141. exit(0);
142.}