C/S通信---服务器IO多路复用模型之poll的使用
2015-11-03 23:58
639 查看
客户端代码同上
服务器端代码:
#include<stdio.h>
#include<sys/socket.h>
#include<unistd.h>
#include<sys/types.h>
#include<errno.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<netinet/in.h>
#include<stdlib.h>
#include<poll.h>
#include<limits.h>
#include<arpa/inet.h>
void handle(struct pollfd* clients, int maxClient, int readyClient);
int main()
{
int socket_fd,connect_fd;
struct sockaddr_in servaddr;
char buff[1024];
char buf[1024];
int n,nready;
struct pollfd clients[1024];
//create socket
if((socket_fd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
printf("create socket error!\n");
exit(0);
}
//set local address
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(8000);
//bind the local addr to socket
if(bind(socket_fd,(struct sockaddr*)&servaddr,sizeof(servaddr)) == -1)
{
printf("bind error %d!\n",errno);
exit(0);
}
//listen client
if(listen(socket_fd,10) == -1)
{
printf("listen error\n");
exit(0);
}
printf("wait for client connection!\n");
clients[0].fd = socket_fd;
clients[0].events = POLLIN;
int i;
for (i = 1; i< 1024; i++)
clients[i].fd = -1;
int maxi = 11;
struct sockaddr_in cliaddr;
socklen_t socklen = sizeof(struct sockaddr_in);
for ( ; ; ) {
nready = poll(clients, maxi + 1, -1); //poll函数有平台限制,不能运行在linux平台
//printf("nready is %d\n", nready);
if (nready == -1) {
perror("poll error");
}
if (clients[0].revents & POLLIN) {
int connfd = accept(socket_fd, (struct sockaddr *) &cliaddr, &socklen);
sprintf(buf, "accept form %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
printf(buf, "");
for (i = 0; i < 1024; i++) {
if (clients[i].fd == -1) {
clients[i].fd = connfd;
clients[i].events = POLLIN;
break;
}
}
if (i == 1024) {
fprintf(stderr, "too many connection, more than %d\n", 1024);
close(connfd);
continue;
}
if (i > maxi)
maxi = i;
--nready;
}
handle(clients, maxi, nready);
}
}
void handle(struct pollfd* clients, int maxClient, int nready) {
int connfd;
int i, nread;
char buf[1024];
if (nready == 0)
return;
for (i = 1; i< maxClient; i++) {
connfd = clients[i].fd;
if (connfd == -1)
continue;
if (clients[i].revents & (POLLIN | POLLERR)) { // revents fd当前实际发生的事件
nread = read(connfd, buf, 1024);//读取客户端socket流
if (nread < 0) {
perror("read error");
close(connfd);
clients[i].fd = -1;
continue;
}
if (nread == 0) {
printf("client close the connection");
close(connfd);
clients[i].fd = -1;
continue;
}
printf("%s",buf);
write(connfd, buf, nread);//响应客户端
if (--nready <= 0)//没有连接需要处理,退出循环
break;
}
}
}
服务器端代码:
#include<stdio.h>
#include<sys/socket.h>
#include<unistd.h>
#include<sys/types.h>
#include<errno.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<netinet/in.h>
#include<stdlib.h>
#include<poll.h>
#include<limits.h>
#include<arpa/inet.h>
void handle(struct pollfd* clients, int maxClient, int readyClient);
int main()
{
int socket_fd,connect_fd;
struct sockaddr_in servaddr;
char buff[1024];
char buf[1024];
int n,nready;
struct pollfd clients[1024];
//create socket
if((socket_fd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
printf("create socket error!\n");
exit(0);
}
//set local address
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(8000);
//bind the local addr to socket
if(bind(socket_fd,(struct sockaddr*)&servaddr,sizeof(servaddr)) == -1)
{
printf("bind error %d!\n",errno);
exit(0);
}
//listen client
if(listen(socket_fd,10) == -1)
{
printf("listen error\n");
exit(0);
}
printf("wait for client connection!\n");
clients[0].fd = socket_fd;
clients[0].events = POLLIN;
int i;
for (i = 1; i< 1024; i++)
clients[i].fd = -1;
int maxi = 11;
struct sockaddr_in cliaddr;
socklen_t socklen = sizeof(struct sockaddr_in);
for ( ; ; ) {
nready = poll(clients, maxi + 1, -1); //poll函数有平台限制,不能运行在linux平台
//printf("nready is %d\n", nready);
if (nready == -1) {
perror("poll error");
}
if (clients[0].revents & POLLIN) {
int connfd = accept(socket_fd, (struct sockaddr *) &cliaddr, &socklen);
sprintf(buf, "accept form %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
printf(buf, "");
for (i = 0; i < 1024; i++) {
if (clients[i].fd == -1) {
clients[i].fd = connfd;
clients[i].events = POLLIN;
break;
}
}
if (i == 1024) {
fprintf(stderr, "too many connection, more than %d\n", 1024);
close(connfd);
continue;
}
if (i > maxi)
maxi = i;
--nready;
}
handle(clients, maxi, nready);
}
}
void handle(struct pollfd* clients, int maxClient, int nready) {
int connfd;
int i, nread;
char buf[1024];
if (nready == 0)
return;
for (i = 1; i< maxClient; i++) {
connfd = clients[i].fd;
if (connfd == -1)
continue;
if (clients[i].revents & (POLLIN | POLLERR)) { // revents fd当前实际发生的事件
nread = read(connfd, buf, 1024);//读取客户端socket流
if (nread < 0) {
perror("read error");
close(connfd);
clients[i].fd = -1;
continue;
}
if (nread == 0) {
printf("client close the connection");
close(connfd);
clients[i].fd = -1;
continue;
}
printf("%s",buf);
write(connfd, buf, nread);//响应客户端
if (--nready <= 0)//没有连接需要处理,退出循环
break;
}
}
}
相关文章推荐
- GUI_台球游戏核心功能开发JAVA077-082
- Mathematica 函数右下标有无的区别
- 【HDU 5532 Almost Sorted Array】水题,模拟
- iOS NSNotificationCenter的简单使用
- iOS UI设计: 在Autolayout自适应的情况下tableviewcell高度自适应
- android:java.lang.NoClassDefFoundError: com.lidroid.xutils.HttpUtils 异常的解决
- 关于WordPress后台设置中的WordPress地址和站点地址的解读
- DisableExplicitGC和Direct ByteBuffer
- 高质量程序设计指南C++/c语言 第四章
- java架构师之路:JAVA程序员必看的15本书的电子版下载地址
- HIHO 16 B
- 如何有效控制需求变更
- Makefile 使用总结
- 控件悬停
- EditPlus4.0汉化+破解注册
- Genymotion启动失败解决方法
- [转]VC++中CTime类Format参数详解
- ListSet_无序表搜索
- JAVA的反射机制
- Android学习记录之Volley框架JSONObjectRequest