头文件:
#ifndef SERVER_HEAD
#define SERVER_HEAD
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <assert.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <netdb.h>
#define PORT 8888
#define PATH "192.168.106.28"
#define MAXSIZE 20
typedef struct work
{
void*(*process)(void* arg);
void* arg;
struct work * next;
}WORK;
typedef struct
{
pthread_mutex_t queue_lock;
pthread_cond_t queue_ready;
WORK * queue_head;
int shutdown;
pthread_t * pthreadid;
int max_thread_num;
int cur_queue_size;
}POOL;
static char name[20][20];
static int sockli[20]={0};
static POOL *pool=NULL;
int sock_create();
void int_bind_listen(int sockfd);
void accept_fun(int sockfd,struct sockaddr_in addr);
void epoll_fun(int sockfd,struct sockaddr_in addr);
void* pthread_routine(void * arg);
void pool_init(int max_num);
int add_work(void*(process)(void *arg),void* arg );
int pool_destroy();
void *task_fun(void *arg);
#endif // SERVER_HEAD
function.c 文件
#include "server3_head.h"
//using namespace std;
//创建套接字
int sock_create()
{
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
perror("socket failed!\n");
exit(1);
}
printf("socket success!\n");
return sockfd;
}
//初始化、绑定、监听
void int_bind_listen(int sockfd)
{
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);
addr.sin_addr.s_addr=inet_addr(PATH);
bzero(addr.sin_zero,8);
if((bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr)))!=0)
{
perror("bind failed!\n");
exit(1);
}
printf("bind success!\n");
if((listen(sockfd,MAXSIZE))!=0)
{
perror("listen failed!\n");
exit(1);
}
printf("listen success!\n");
}
//epoll监听函数
void epoll_fun(int sockfd,struct sockaddr_in addr)
{
int i,j=0;
int epfd;
int newfd;
int evnum;
int recbytes;
struct epoll_event ep;
struct epoll_event events[MAXSIZE];
socklen_t addr_len=sizeof(struct sockaddr);
epfd=epoll_create(MAXSIZE);
ep.data.fd =sockfd;
ep.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&ep);
while(1)
{
evnum=epoll_wait(epfd,events,MAXSIZE,-1);
if(evnum==0)
{
printf("time out!\n");
}
else if(evnum==-1)
{
printf("stop at this time forever!\n") ;
}
else{
printf("epoll success!evnum=%d\n",evnum);
}
for(int i=0;i<evnum;i++)
{
if(events[i].data.fd==sockfd)
{
newfd=accept(sockfd,(struct sockaddr *)&addr,&addr_len);
if(newfd==-1)
{
perror("accept failed!\n");
}
else
{
sockli[j]=newfd;
printf("%d\n",sockli[j]);
j++;
ep.data.fd =newfd;
ep.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_ADD,newfd,&ep);
}
}
else if(events[i].events&EPOLLIN)
{
ep.data.fd =events[i].data.fd;
ep.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_MOD,ep.data.fd,&ep);
add_work(task_fun,(void *)(events[i].data.fd));
}
}
}
}
//服务器接收客户端链接函数
void accept_fun(int sockfd,struct sockaddr_in addr)
{
int recvbytes=0;
int i=0;
int ret=-1;
socklen_t addr_len=sizeof(struct sockaddr);
while(1)
{
sockli[i]=accept(sockfd,(struct sockaddr*)&addr,&addr_len);
if(sockli[i]<0)
{
perror("accept failed!\n");
}
else{
printf("accept success!\n");
}
recvbytes=recv(sockli[i],name[i],20,0);
if(recvbytes==-1)
{
perror("recv failed in accept_fun!\n");
}else
{
printf("recv %d bytes to name\n");
name[i][recvbytes]='\0';
printf("name=%s\n",name[i]);
}
printf("i=%d\n",i);
printf("%d\n",sockli[i]);
ret=add_work((task_fun),(void*) i);
if(ret!=0)
{
perror("add failed!\n");
}
i++;
}
}
/*
//回调函数
void* task_fun(void * arg)
{
int a=(int)arg;
printf("%d\n",sockli[(a)]);
sleep(5);
int recvbytes=0;
int i,j,k;
int sent=0;
char news[100];
while(1)
{
recvbytes=recv(sockli[a],news,sizeof(news),0);
if ( recvbytes == -1)
{
perror("recv failed in task_fun!\n");
}
else if(recvbytes==0)
{
printf("client is closed!\n");
break;
}
else{
printf("recv %d bytes from client\n",recvbytes);
news[recvbytes]='\0';
printf("news=%s\n",news);
}
for(j=0;sockli[j]!=0;j++)
{
if(sockli[j]==sockli[a])
{
continue;
}
sent=send(sockli[j],name[a],strlen(name[a]),0);
sent=send(sockli[j],news,strlen(news),0);
if(sent==-1)
{
perror("send failed!\n");
}
else{
printf("send %d bytes to client\n",sent);
}
}
}
pthread_exit(NULL);
}
*/
//回调函数 epoll
void* task_fun(void * arg)
{
printf("aaaaaaaaaaa\n");
int a=(int)arg;
int recvbytes=0;
int i,j,k;
int sent=0;
char news[100];
while(1)
{
recvbytes=recv(a,news,sizeof(news),0);
if ( recvbytes == -1)
{
perror("recv failed in task_fun!\n");
}
else if(recvbytes==0)
{
printf("client is closed!\n");
break;
}
else{
printf("recv %d bytes from client\n",recvbytes);
news[recvbytes]='\0';
printf("news=%s\n",news);
}
for(j=0;sockli[j]!=0;j++)
{
if(sockli[j]==a)
{
continue;
}
// sent=send(sockli[j],name[a],strlen(name[a]),0);
sent=send(sockli[j],news,strlen(news),0);
if(sent==-1)
{
perror("send failed!\n");
}
else{
printf("send %d bytes to client\n",sent);
}
}
}
pthread_exit(NULL);
}
//线程处理函数
void* pthread_routine(void *args)
{
printf("this is in pthread_routine\n");
while(1)
{
pthread_mutex_lock(&(pool->queue_lock));
while(pool->cur_queue_size==0&& !pool->shutdown)
{
pthread_cond_wait(&(pool->queue_ready),&(pool->queue_lock));
}
if(pool->shutdown)
{
pthread_mutex_unlock(&(pool->queue_lock));
pthread_exit(NULL);
}
printf("ready to start\n");
assert(pool->cur_queue_size !=0);
assert(pool->queue_head !=NULL);
pool->cur_queue_size--;
WORK* worker=pool->queue_head;
pool->queue_head=worker->next;
pthread_mutex_unlock(&(pool->queue_lock));
(*(worker->process))(worker->arg);
free(worker);
worker=NULL;
}
pthread_exit(NULL);
}
// 线程池初始化
void pool_init(int max_num)
{
int i;
pool=(POOL*)malloc(sizeof(POOL));
pthread_mutex_init(&(pool->queue_lock),NULL);
pthread_cond_init(&(pool->queue_ready),NULL);
pool->queue_head=NULL;
pool->max_thread_num=max_num;
pool->cur_queue_size=0;
pool->pthreadid=(pthread_t *)malloc((pool->max_thread_num) * sizeof(pthread_t));
for(i=0;i<max_num;i++)
{
pthread_create(&(pool->pthreadid[i]),NULL,pthread_routine,NULL);
printf("%d\n",pool->pthreadid[i]);
}
}
//添加任务队列
int add_work(void*(process)(void* arg),void *arg)
{
WORK* newwork=(WORK*)malloc(sizeof(WORK));
newwork->process=process;
newwork->arg=arg;
newwork->next=NULL;
pthread_mutex_lock(&(pool->queue_lock));
WORK* member=pool->queue_head;
if(member !=NULL)
{
while(member->next !=NULL)
{
member=member->next;
}
}
else{
pool->queue_head=newwork;
}
assert(pool->queue_head !=NULL);
pool->cur_queue_size ++;
pthread_mutex_unlock(&(pool->queue_lock));
pthread_cond_signal(&(pool->queue_ready));
return 0;
}
//清空线程池
int pool_destroy()
{
if(pool->shutdown)
{
return -1;
}
pool->shutdown=-1;
pthread_cond_broadcast(&(pool->queue_ready));
int i;
for(i=0;i<pool->max_thread_num;i++)
{
pthread_join((pool->pthreadid[i]),NULL);
}
free(pool->pthreadid);
WORK* head=NULL;
while(pool->queue_head !=NULL)
{
head=pool->queue_head;
pool->queue_head=pool->queue_head->next;
free(head);
}
pthread_mutex_destroy(&(pool->queue_lock));
pthread_cond_destroy(&(pool->queue_ready));
free(pool);
pool=NULL;
}
main.c 文件
#include "server3_head.h"
int main()
{
int sockfd;
struct sockaddr_in client_addr;
pool_init(10);
sockfd=sock_create();
int_bind_listen(sockfd);
epoll_fun(sockfd,client_addr);
pool_destroy();
return 0;
}