#define _GNU_SOURCE 1
#include<unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#include <netdb.h>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <poll.h>
#define DEF_STD_ERROR (-1)
#define DEF_BIND_PORT (12455)
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#define BOOL int
#endif
//set socket(TRUE:block, FALSE:no block)
void set_block(int sock,BOOL flag)
{
int ret;
if(flag == TRUE)
{
ret = fcntl(sock,F_GETFL);
ret ^= O_NONBLOCK;//ret &= (~O_NONBLOCK);
fcntl(sock,F_SETFL,ret);
}
else
{
ret = fcntl(sock,F_GETFL);
ret |= O_NONBLOCK;
fcntl(sock,F_SETFL,ret);
}
}
//thread param
struct thread_param
{
struct pollfd fds[1000];
int my_count;
pthread_mutex_t my_mutex;
};
void *deal_thread(void *param)
{
struct thread_param *p = (struct thread_param*)param;
int ret;
int i;
char buf[1024];
while(1)
{
//poll
ret = poll(p->fds,p->my_count,10);
//judge
if(ret < 0)
{
printf("%s\n",strerror(errno));
break;
}
else if(ret == 0)
{
usleep(10);
continue;
}
//check
for(i= 0;i < p->my_count ;++i)
{
//peer force close socket
if(POLLERR &p->fds[i].revents)
{
//delete client
pthread_mutex_lock(&p->my_mutex);
close(p->fds[i].fd);
printf("client:force:[%d] quit!\n",p->fds[i].fd);
p->fds[i] = p->fds[--p->my_count];
pthread_mutex_unlock(&p->my_mutex);
}
else if(POLLRDHUP &p->fds[i].revents)
{
//delete client
pthread_mutex_lock(&p->my_mutex);
close(p->fds[i].fd);
printf("client:happy:[%d] quit!\n",p->fds[i].fd);
p->fds[i] = p->fds[--p->my_count];
pthread_mutex_unlock(&p->my_mutex);
}
else if(POLLIN &p->fds[i].revents)
{
//recv
ret = recv(p->fds[i].fd,buf,sizeof(buf),0);
printf("client:[%d] [%s]",p->fds[i].fd,buf);
p->fds[i].events = POLLOUT;
}
else if(POLLOUT &p->fds[i].revents)
{
//send and no block
send(p->fds[i].fd,buf,strlen(buf)+1,0);
p->fds[i].events = POLLIN | POLLERR | POLLRDHUP;
}
}
}
}
int main(int argc,char *argv[])
{
int ret;
int sock;
struct sockaddr_in addr;
char buf[1024];
int len;
pthread_t thread;
fd_set read_set;
struct thread_param param;
param.my_count = 0;
pthread_mutex_init(¶m.my_mutex,NULL);
//create socket
sock = socket(AF_INET,SOCK_STREAM,0);
if(sock == DEF_STD_ERROR)
{
printf("%s",strerror(errno));
return -1;
}
//init address
addr.sin_family = AF_INET;
addr.sin_port = htons(DEF_BIND_PORT);
addr.sin_addr.s_addr = inet_addr("192.168.1.127");
//bind
ret = bind(sock,(struct sockaddr*)&addr,sizeof(addr));
if(ret == DEF_STD_ERROR)
{
printf("%s",strerror(errno));
close(sock);
return -1;
}
//listen
ret = listen(sock,5);
if(ret == DEF_STD_ERROR)
{
printf("%s",strerror(errno));
close(sock);
return -1;
}
//set no block
set_block(sock,FALSE);
//accept
while(1)
{
ret = accept(sock,NULL,NULL);
if(ret == DEF_STD_ERROR)
{
if(errno == EAGAIN)
{
//printf("yi bu...\n");
usleep(10);
continue;
}
else
{
printf("%s",strerror(errno));
break;
}
}
//add to read_set
pthread_mutex_lock(¶m.my_mutex);
if(param.my_count < 1024)
{
param.fds[param.my_count].fd = ret;
param.fds[param.my_count].events = POLLIN | POLLERR | POLLRDHUP;
param.my_count++;
}
//if is first ,create thread
if(param.my_count == 1)
{
pthread_create(&thread,NULL,deal_thread,¶m);
}
pthread_mutex_unlock(¶m.my_mutex);
}
//wait child thread
pthread_join(thread,NULL);//WaitForSignalObject
//pthread_mutex_destory(¶m.my_mutex);
//close
close(sock);
return 0;
}
Linux网络poll模型
最新推荐文章于 2023-09-18 15:02:05 发布