免费搭建视频网站,购物商城网站建设公司,网站主页设计模板,杭州排名优化软件本章节是用基本的Linux基本函数加上epoll调用编写一个完整的服务器和客户端例子#xff0c;可在Linux上运行#xff0c;客户端和服务端的功能如下:
客户端从标准输入读入一行#xff0c;发送到服务端
服务端从网络读取一行#xff0c;然后输出到客户端
客户端收到服务端…本章节是用基本的Linux基本函数加上epoll调用编写一个完整的服务器和客户端例子可在Linux上运行客户端和服务端的功能如下:
客户端从标准输入读入一行发送到服务端
服务端从网络读取一行然后输出到客户端
客户端收到服务端的响应输出这一行到标准输出 服务端
代码如下: #include unistd.h
#include sys/types.h /* basic system data types */
#include sys/socket.h /* basic socket definitions */
#include netinet/in.h /* sockaddr_in{} and other Internet defns */
#include arpa/inet.h /* inet(3) functions */
#include sys/epoll.h /* epoll function */
#include fcntl.h /* nonblocking */
#include sys/resource.h /*setrlimit */#include stdlib.h
#include errno.h
#include stdio.h
#include string.h#define MAXEPOLLSIZE 10000
#define MAXLINE 10240
int handle(int connfd);
int setnonblocking(int sockfd)
{if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) -1) {return -1;}return 0;
}int main(int argc, char **argv)
{int servPort 6888;int listenq 1024;int listenfd, connfd, kdpfd, nfds, n, nread, curfds,acceptCount 0;struct sockaddr_in servaddr, cliaddr;socklen_t socklen sizeof(struct sockaddr_in);struct epoll_event ev;struct epoll_event events[MAXEPOLLSIZE];struct rlimit rt;char buf[MAXLINE];/* 设置每个进程允许打开的最大文件数 */rt.rlim_max rt.rlim_cur MAXEPOLLSIZE;if (setrlimit(RLIMIT_NOFILE, rt) -1) {perror(setrlimit error);return -1;}bzero(servaddr, sizeof(servaddr));servaddr.sin_family AF_INET; servaddr.sin_addr.s_addr htonl (INADDR_ANY);servaddr.sin_port htons (servPort);listenfd socket(AF_INET, SOCK_STREAM, 0); if (listenfd -1) {perror(cant create socket file);return -1;}int opt 1;setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, opt, sizeof(opt));if (setnonblocking(listenfd) 0) {perror(setnonblock error);}if (bind(listenfd, (struct sockaddr *) servaddr, sizeof(struct sockaddr)) -1) {perror(bind error);return -1;} if (listen(listenfd, listenq) -1) {perror(listen error);return -1;}/* 创建 epoll 句柄把监听 socket 加入到 epoll 集合里 */kdpfd epoll_create(MAXEPOLLSIZE);ev.events EPOLLIN | EPOLLET;ev.data.fd listenfd;if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listenfd, ev) 0) {fprintf(stderr, epoll set insertion error: fd%d\n, listenfd);return -1;}curfds 1;printf(epollserver startup,port %d, max connection is %d, backlog is %d\n, servPort, MAXEPOLLSIZE, listenq);for (;;) {/* 等待有事件发生 */nfds epoll_wait(kdpfd, events, curfds, -1);if (nfds -1){perror(epoll_wait);continue;}/* 处理所有事件 */for (n 0; n nfds; n){if (events[n].data.fd listenfd) {connfd accept(listenfd, (struct sockaddr *)cliaddr,socklen);if (connfd 0) {perror(accept error);continue;}sprintf(buf, accept form %s:%d\n, inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);printf(%d:%s, acceptCount, buf);if (curfds MAXEPOLLSIZE) {fprintf(stderr, too many connection, more than %d\n, MAXEPOLLSIZE);close(connfd);continue;} if (setnonblocking(connfd) 0) {perror(setnonblocking error);}ev.events EPOLLIN | EPOLLET;ev.data.fd connfd;if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, connfd, ev) 0){fprintf(stderr, add socket %d to epoll failed: %s\n, connfd, strerror(errno));return -1;}curfds;continue;} // 处理客户端请求if (handle(events[n].data.fd) 0) {epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,ev);curfds--;}}}close(listenfd);return 0;
}
int handle(int connfd) {int nread;char buf[MAXLINE];nread read(connfd, buf, MAXLINE);//读取客户端socket流
if (nread 0) {printf(client close the connection\n);close(connfd);return -1;} if (nread 0) {perror(read error);close(connfd);return -1;} write(connfd, buf, nread);//响应客户端 return 0;
} 下载和编译
下载地址
编译和启动服务端 gcc epollserver.c -o epollserver
./epollserver 至于客户端可以参考本文的Linux/Unix服务端和客户端Socket编程入门实例的echoclient例子下载编译。