epoll函数是线程安全的

#include // for sockaddr_in#include // for socket#include // for socket#include // for printf#include // for exit#include // for bzero#include #include #define HELLO_WORLD_SERVER_PORT 9999 #define BUFFER_SIZE 1024#define SERV_HOST_ADDR "127.0.0.1"void *client(void *p_param){int iret = -1; //设置一个socket地址结构client_addr,代表客户机internet地址, 端口 struct sockaddr_in client_addr; bzero(&client_addr,sizeof(client_addr)); //把一段内存区的内容全部设置为0 client_addr.sin_family = AF_INET; //internet协议族 client_addr.sin_addr.s_addr = htons(INADDR_ANY);//INADDR_ANY表示自动获取本机地址 client_addr.sin_port = htons(0); //0表示让系统自动分配一个空闲端口 //创建用于internet的流协议(TCP)socket,用client_socket代表客户机socket int client_socket = socket(AF_INET,SOCK_STREAM,0); if( client_socket < 0) { printf("Create Socket Failed!\n"); exit(1); } //把客户机的socket和客户机的socket地址结构联系起来 if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr))) { printf("Client Bind Port Failed!\n"); exit(1); } //设置一个socket地址结构server_addr,代表服务器的internet地址, 端口 struct sockaddr_in server_addr; bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = inet_addr (SERV_HOST_ADDR); server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); socklen_t server_addr_length = sizeof(server_addr); //向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接 if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0) { printf("Can Not Connect To server\n"); exit(1); } char buffer[BUFFER_SIZE]; bzero(buffer,BUFFER_SIZE); strcpy(buffer,"Hello, World! From Client\n");printf("client thread id = %d\n", pthread_self());while (1){//向服务器发送buffer中的数据iret = send(client_socket,buffer,BUFFER_SIZE,0);if (iret == -1){printf("send error\n");break;}else{printf("thread %d send %d byte\n", pthread_self(), iret);sleep(1);}}//关闭socket close(client_socket);}int main(int argc, char **argv){int i = 0;int max_thread=1000;pthread_t threadID[1024];int iret = 0;for (i = 0; i < max_thread; i++){// printf("CREATE THREAD PPID = %d\n", )iret = pthread_create(&threadID[i], NULL, client, NULL);if (0 != iret){printf("create thread error errno = %d, strerror = %s\n", errno, strerror(errno));}}while(1){sleep(1);} return 0;}#include #include #include #include #include #include #include #include #include #include #include #define EPOLL_MAX_EVENT (1000)#define MAXMSG (1000)int g_sockfd = -1;int g_epollfd = -1;struct epoll_event g_EpollEvent[EPOLL_MAX_EVENT];pthread_t threadID[8] = {0};int epoll_set_no_blocking(int iSockFd){ int iOpts = 0; iOpts = fcntl(iSockFd, F_GETFL); if ( -1 == iOpts ) { printf("epoll_set_no_blocking:get opt failed\n"); return -1; } iOpts = iOpts | O_NONBLOCK; iOpts = fcntl(iSockFd, F_GETFL, iOpts); if ( -1 == iOpts ) { printf("epoll_set_no_blocking:set opt failed\n"); return -1; } return 0;}int epoll_add(int iEpollFd, int iFd){ int iRet = -1; struct epoll_event env; memset(&env, 0, sizeof(env)); env.events = EPOLLIN | EPOLLET; env.data.fd = iFd; iRet = epoll_ctl(iEpollFd, EPOLL_CTL_ADD, iFd, &env); if ( -1 == iRet ) { printf("epoll_add:epoll_ctl failed\n"); return -1; } return 0;}ssize_t /* Read "n" bytes from a descriptor. */readn(int fd, void *vptr, size_t n){size_t nleft;ssize_t nread;char *ptr;ptr = vptr;nleft = n;while (nleft > 0) {if ( (nread = read(fd, ptr, nleft)) < 0) {if (errno == EINTR){nread = 0; /* and call read() again */} else if (errno == EWOULDBLOCK || errno == EAGAIN){printf("EAGAIN = %d EWOULDBLOCK = %d errno = %d\n", EAGAIN, EWOULDBLOCK, errno);break;} elsereturn(-1);} else if (nread == 0)break; /* EOF */nleft -= nread;ptr += nread;}return(n - nleft); /* return >= 0 */}void *epoll_main_loop(void *p_param){int i = 0;int nFds = 0;struct epoll_event ev; int conn_sock = 0;struct sockaddr local;int addrlen = 0; for (;;) { nFds = epoll_wait(g_epollfd, g_EpollEvent, EPOLL_MAX_EVENT, -1); if ( -1 == nFds ) { printf("main_loop: epoll_wait failed\n"); continue; }printf("threadid = %d nFds = %d\n", pthread_self(), nFds); for ( i = 0; i < nFds; i++ ) { if (g_EpollEvent[i].data.fd == g_sockfd) { conn_sock = accept(g_sockfd, (struct sockaddr *) &local, &addrlen); if (conn_sock == -1) { perror("accept"); exit(EXIT_FAILURE); } epoll_set_no_blocking(conn_sock); memset(&ev, 0,sizeof(ev)); ev.events = EPOLLIN | EPOLLET; ev.data.fd = conn_sock; if (epoll_ctl(g_epollfd, EPOLL_CTL_ADD, conn_sock, &ev) == -1) { perror("epoll_ctl: conn_sock"); exit(EXIT_FAILURE); }} if ( g_EpollEvent[i].events & EPOLLIN ) {int len;int n = 0;char msg[MAXMSG];struct sockaddr_in cli_addr;len = sizeof(struct sockaddr_in);n = readn(g_EpollEvent[i].data.fd, msg, MAXMSG);printf("thread %d g_EpollEvent[i].data.fd = %d read n = %d byte\n", pthread_self(), g_EpollEvent[i].data.fd, n); } }}}int main(){int iRet = -1;int one = 1;int epollCount = EPOLL_MAX_EVENT;int nfd = -1;struct sockaddr_in serv_addr;struct epoll_event env;memset(&serv_addr, 0, sizeof(struct sockaddr_in));g_sockfd = socket(AF_INET, SOCK_STREAM , 0); if ( -1 == g_sockfd ){printf("create socket failed\n");return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);serv_addr.sin_port = htons(9999);iRet = setsockopt(g_sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));if ( -1 == iRet ){printf("setsockopt SO_RCVBUF failed errno = %s\n", strerror(errno));return -1;}one = 1024 * 1024;if( setsockopt(g_sockfd, SOL_SOCKET, SO_RCVBUF, &one, sizeof(one) ) < 0 ){printf("setsockopt SO_RCVBUF failed errno = %s\n", strerror(errno));return -1;}iRet = bind(g_sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));if ( -1 == iRet ){printf("bind failed\n");return -1;}iRet = listen(g_sockfd, 5);if ( -1 == iRet ){printf("listen failed\n");return -1;}g_epollfd = epoll_create(epollCount);if ( -1 == g_epollfd ){printf("create epoll failed\n");return 0;}iRet = epoll_add(g_epollfd, g_sockfd);if ( -1 == iRet ){printf("listen failed\n");return -1;}// create thread poll int i = 0;for (i = 0; i < 8; i++){if (pthread_create (&threadID[i], NULL,epoll_main_loop, NULL)) //process auth{exit(1);}}while (1){//nfd = epoll_wait(g_epollfd, )sleep(1);}return 0; }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值