#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include "InterCommunicationModel.h"
//#include "common.h"
/*
* Copyright (C) 2013 yangguo <yangguo@yangguo-ubuntu 12.4LTS>
*******************************************************************
* project name:
* Function:
*******************************************************************
* created time:2013-08-19-11.15
* company:dbc.com.ltd
* version:1.0
*******************************************************************
* support email:guoyang2011@gmail.com
* main function:
* modify information:None
*******************************************************************
*/
#define MAX_FREE_SIZE 100
/*******************************************************************
*****************************************************************
主要维护服务器端与客户端、节点服务器、服务器其他模块通信
包含功能:
1.维护整个通信模块的正常工作;
2.维护与节点服务器的通信功能;
*****************************************************************
*******************************************************************
*/
struct MasterDataPoolType
{
struct MasterTransDataType *header;
struct MasterTransDataType *freeHeader;
int condition;
int freeCondition;
pthread_mutex_t mutex;
pthread_cond_t cond;
pthread_mutex_t freeMutex;
};
#define MSGLENGTH 1024
static SockInfoPool slaverSockManager;
static SockInfoPool clientSockManager;
static struct MasterDataPoolType masterDataInPool;//输入任务链表
static struct MasterDataPoolType masterDataOutPool;//输出任务链表
//>>>>>>>>>>>>>>>>维护数据链表>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
/*
主要用于服务器端端模块之间数据通信
*/
static void InitMasterDataPool(struct MasterDataPoolType *masterPool)
{
masterPool->header=NULL;
masterPool->freeHeader=NULL;
masterPool->condition=0;
masterPool->freeCond=0;
pthread_mutexattr_t mutexattr;
pthread_condattr_t condattr;
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&masterPool->mutex,&mutexattr);
pthread_mutex_init(&masterPool->freeMutex,&mutexattr);
pthread_condattr_init(&condattr);
pthread_condattr_setpshared(&condattr,PTHREAD_PROCESS_SHARED);
pthread_cond_init(&masterPool->cond,&condattr);
}
static struct MasterTransDataType *MallocInResource()
{
struct MasterTransDataType *result=NULL;
pthread_mutex_lock(&masterDataInPool->freeMutex);
if(masterDataInPool->freeCondition<=0)
{
result=((struct MasterTransDataType *)malloc(sizeof(struct MasterTransDataType)));
}
else
{
result=masterDataInPool->freeHeader;
masterDataInPool->freeHeader=masterDataInPool->freeHeader->next;
masterDataInPool->freeCondition--;
}
pthread_mutex_unlock(&masterDataInPool->freeMutex);
//memset(result,0,sizeof(struct MasterTransDataType));
return result;
}
void freeInResource(struct MasterTransDataType *freeValue)
{
pthread_mutex_lock(&masterDataInPool->freeMutex);
if(masterDataInPool->freeCondition>MAX_FREE_SIZE)
{
free(freeValue);
}
else
{
freeValue->next=masterDataInPool->freeHeader;
masterDataInPool->freeHeader=freeValue;
masterDataInPool->freeCondtion++;
}
pthread_mutex_unlock(&masterDataInPool->freeMutex);
}
struct MasterTransDataType *GetTaskFromInPool()
{
struct MasterTransDataType *result=NULL;
pthread_mutex_lock(&masterDataInPool->mutex);
while(masterDataInPool->condition==0)
{
pthread_cond_wait(&masterDataInPool->cond,&masterDataInPool->mutex);
}
result=masterDataInPool->header;
masterDataInPool->header=masterDataInPool->header->next;
masterDataInPool->condition--;
pthread_mutex_unlock(&masterDataInPool->mutex);
return result;
}
static void AddTaskToInPool(const struct MasterTransDataType *value)
{
struct MasterTransDataType *temp=MallocInResource();
if(temp==NULL)
{
temp=((struct MasterTransDataType *)malloc(sizeof(struct MasterTransDataType)));
}
memset(temp,0,sizeof(struct MasterTransDataType));
memcpy(temp,value,sizeof(struct MasterTransDataType));
pthread_mutex_lock(&masterDataInPool->mutex);
temp->next=masterDataInPool->header;
masterDataInPool->header=temp;
masterDataInPool->condition++;
pthread_mutex_unlock(&masterDataInPool->mutex);
pthread_cond_signal(&masterDataInPool->cond);
}
/*
static struct SlaverTransDataType *ReadMallocInResource(struct CommunicationManagerType *readPool)
{
if(readPool->freeCondition==0||readPool->freeHeader==NULL)
{
return ((struct SlaverTransDataType *)malloc(sizeof(struct SlaverTransDataType)));
}
else
{
struct SlaverTransDataType *result=readPool->freeHeader;
readPool->freeHeader=readPool->freeHeader->next;
readPool->freeCondition--;
return result;
}
}
*/
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<向客户端、节点服务器发送数据<<<<<<<<<<<<<<<<<<<<<
struct MasterTransDataType *MallocOutResource()
{
struct MasterTransDataType *result=NULL;
pthread_mutex_lock(&masterDataOutPool->freeMutex);
if(masterDataOutPool->freeCondition<=0)
{
result=((struct MasterTransDataType *)malloc(sizeof(struct MasterTransDataType)));
}
else
{
result=masterDataOutPool->freeHeader;
masterDataOutPool->freeHeader=masterDataOutPool->freeHeader->next;
masterDataOutPool->freeCondition--;
}
pthread_mutex_unlock(&masterDataOutPool->freeMutex);
//memset(result,0,sizeof(struct MasterTransDataType));
return result;
}
void AddTaskToOutPool(const struct MasterTransDataType *value)
{
struct MasterTransDataType *temp=MallocInResource();
if(temp==NULL)
{
temp=((struct MasterTransDataType *)malloc(sizeof(struct MasterTransDataType)));
}
memset(temp,0,sizeof(struct MasterTransDataType));
memcpy(temp,value,sizeof(struct MasterTransDataType));
pthread_mutex_lock(&masterDataOutPool->mutex);
temp->next=masterDataOutPool->header;
masterDataOutPool->header=temp;
masterDataOutPool->condition++;
pthread_mutex_unlock(&masterDataOutPool->mutex);
pthread_cond_signal(&masterDataOutPool->cond);
}
static void freeOutResource(struct MasterTransDataType *freeValue)
{
pthread_mutex_lock(&masterDataOutPool->freeMutex);
if(masterDataOutPool->freeCondition>MAX_FREE_SIZE)
{
free(freeValue);
}
else
{
freeValue->next=masterDataOutPool->freeHeader;
masterDataOutPool->freeHeader=freeValue;
masterDataOutPool->freeCondtion++;
}
pthread_mutex_unlock(&masterDataOutPool->freeMutex);
}
static struct MasterTransDataType *GetTaskFromOutPool()
{
struct MasterTransDataType *result=NULL;
pthread_mutex_lock(&masterDataOutPool->mutex);
while(masterDataOutPool->condition==0)
{
pthread_cond_wait(&masterDataOutPool->cond,&masterDataOutPool->mutex);
}
result=masterDataOutPool->header;
masterDataOutPool->header=masterDataOutPool->header->next;
masterDataOutPool->condition--;
pthread_mutex_unlock(&masterDataOutPool->mutex);
return result;
}
static void *RunSendMsgThread(void *tempValue)
{
struct MasterTransDataType *value;
int result=-1;
for(;;)
{
value=GetTaskFromOutPool();
if(value!=NULL)
{
result=send(value->c_info.c_sockfd,&value->data,sizeof(struct ExchangeDataType),0);
freeOutResource(value);
}
}
return NULL;
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<维护服务器端监听客户端和节点服务器套接字添加删除,数据接收等操作,由模块自动维护<<
static void InitSockManagers(SockInfoPool *sockPool,const char *addr,const int ListenPort)
{
sockPool->c_header=NULL;
sockPool->slaverSockNum=0;
sockPool->serverInfo.epollSockfd=-1;
sockPool->serverInfo.eventListenSize=20;
sockPool->serverInfo.sockPort=ListenPort;
sockPool->serverInfo.listenSize=40000;
sockPool->serverInfo.mainSockfd=-1;
memcpy(sockPool->serverInfo.addr,addr,strlen(addr));
pthread_rwlockattr_t rwlockattr;
pthread_rwlockattr_init(&rwlockattr);
pthread_rwlockattr_setpshared(&rwlockattr,PTHREAD_PROCESS_SHARED);
pthread_rwlock_init(&(sockPool->rwlock),&rwlockattr);
}
static int CreateEpollFD(int *mainSockfd,const int listenSize,const char *addr,const int port)
{
int epollSockfd,serverfd;
struct sockaddr_in serverSockAddr;
struct epoll_event epev;
InitAddr(&serverSockAddr,addr,port);
serverfd=socket(AF_INET,SOCK_STREAM,0);
*mainSockfd=serverfd;
if(serverfd==-1)
{
return -1;
}
epollSockfd=epoll_create(listenSize);
if(epollSockfd==-1)
{
return -2;
}
epev.data.fd=serverfd;
epev.events=EPOLLIN|EPOLLET;
epoll_ctl(epollSockfd,EPOLL_CTL_ADD,serverfd,&epev);
if(bind(serverfd,(struct sockaddr *)&serverSockAddr,sizeof(struct sockaddr))==-1)
{
return -3;
}
if(listen(serverfd,listenSize)==-1)
{
return -4;
}
return epollSockfd;
}
static void InitAddr(struct sockaddr_in *iSockAddr,const char *addr,const int port)
{
bzero(&(iSockAddr->sin_zero),0);
iSockAddr->sin_family=AF_INET;
iSockAddr->sin_port=htons(port);
iSockAddr->sin_addr.s_addr=inet_addr(addr);
}
/*
struct ClientSockInfoType
{
int c_sockfd;
struct sockaddr c_addr;
};
typedef struct BaseSockInfo//Epoll中监听套接字数据结构
{
struct BaseSockInfo *c_next;
struct ClientSockInfoType c_Info;
}SockInfo;
*/
static void ThreadRun(void *arg)
{
SockInfoPool *sockPool=(SockInfoPool *)arg;
struct epoll_event events[sockPool->serverInfo.eventListenSize];
struct epoll_event ev;
struct MasterTransDataType *recvDataPtr;//AddTaskToInPool(const struct MasterTransDataType *value)
int eventsNum=0,i=0,recvNum;
int addrLen=sizeof(struct sockaddr);
SockInfo *tempSockInfo;
sockPool->serverInfo.epollSockfd=CreateEpollFD(&sockPool->serverInfo.mainSockfd,sockPool->serverInfo.listenSize,sockPool->serverInfo.addr,sockPool->serverInfo.sockPort);
if(sockPool->serverInfo.epollSockfd<0)
{
return ;
}
for(;;)
{
eventsNum=epoll_wait(sockPool->serverInfo.epollSockfd,events,sockPool->serverInfo.eventListenSize,3000);
//printf("eventsNum Value :%d\n",eventsNum);
for(i=0;i<eventsNum;i++)
{
if(events[i].data.fd==sockPool->serverInfo.mainSockfd)//新连接加入
{
tempSockInfo=(SockInfo *)malloc(sizeof(SockInfo));
memset(tempSockInfo,0,sizeof(SockInfo));
tempSockInfo->c_Info.c_sockfd=accept(sockPool->serverInfo.mainSockfd,&tempSockInfo->c_Info.c_addr,&addrLen);
if(tempSockInfo->c_Info.c_sockfd<0)
{
continue;
}
else
{
AddNewSockInfo(sockPool,tempSockInfo);
ev.data.fd=tempSockInfo->c_Info.c_sockfd;
ev.events=EPOLLIN|EPOLLIN;
epoll_ctl(sockPool->serverInfo.epollSockfd,EPOLL_CTL_ADD,tempSockInfo->c_Info.c_sockfd,&ev);
}
}
else if(events[i].events&&EPOLLIN)
{
//////////////////////////////////////////////////////////////////
//*接收数据模块*/
recvDataPtr=MallocInResource();
if(recvDataPtr==NULL)
{
recvDataPtr=(struct MasterTransDataType *)malloc(sizeof(struct MasterTransDataType));
}
memset(recvDataPtr,0,sizeof(struct MasterTransDataType));
recvNum=read(events[i].data.fd,&recvDataPtr->data,sizeof(struct ExchangeDataType));
if(recvNum<0)
{
if(errno==ECONNRESET)
{
ev=events[i];
epoll_ctl(sockPool->serverInfo.epollSockfd,EPOLL_CTL_DEL,events[i].data.fd,&ev);
close(events[i].data.fd);
DeleteSockInfo(sockPool,events[i].data.fd);
}
else
{
continue;
}
}
else
{
//接收到来自slaver端或客户端的数据添加到数据链表中
recvDataPtr->c_info->c_sockfd=events[i].data.fd;
AddTaskToInPool(recvDataPtr);
}
//////////////////////////////////////////////////////////////////
}
}
}
}
static int AddNewSockInfo(SockInfoPool *sockPool,SockInfo *tempInfo)
{
if(IsExits(sockPool,tempInfo->c_Info.c_sockfd)==0)
{
pthread_rwlock_wrlock(&sockPool->rwlock);
tempInfo->c_next=sockPool->c_header;
sockPool->c_header=tempInfo;
sockPool->slaverSockNum++;
pthread_rwlock_unlock(&sockPool->rwlock);
return 0;
}
else
{
return 1;
}
}
static int IsExits(const SockInfoPool *sockPool,const int sockid)
{
int result=0;
SockInfo *tempSock=sockPool->c_header;
pthread_rwlock_rdlock(&(sockPool->rwlock));
while(tempSock!=NULL)
{
if(tempSock->c_Info.c_sockfd==sockid)
{
result=1;
break;
}
else
{
tempSock=tempSock->c_next;
}
}
pthread_rwlock_unlock(&(sockPool->rwlock));
return result;
}
static int DeleteSockInfo(SockInfoPool *sockPool,const int sockid)
{
int result=0;
SockInfo *pre,*tempSock;
tempSock=sockPool->c_header;
pthread_rwlock_wrlock(&sockPool->rwlock);
if(tempSock->c_Info.c_sockfd==sockid)
{
sockPool->c_header=sockPool->c_header->c_next;
sockPool->slaverSockNum--;
free(tempSock);
result=1;
}
else
{
pre=tempSock;
tempSock=tempSock->c_next;
while(tempSock!=NULL)
{
if(tempSock->c_Info.c_sockfd==sockid)
{
pre->c_next=tempSock->c_next;
free(tempSock);
sockPool->slaverSockNum--;
result=1;
break;
}
else
{
pre=tempSock;
tempSock=tempSock->c_next;
}
}
}
pthread_rwlock_unlock(&sockPool->rwlock);
return result;
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
int RunListen(const int slaverListenPort,const int clientListenPort,const char *addr)
{
int i;
pthread_t *tid=(pthread_t *)malloc(3*sizeof(pthread_t));
InitSockManagers(&slaverSockManager,addr,slaverListenPort);
InitSockManagers(&clientSockManager,addr,clientListenPort);
InitMasterDataPool(&masterDataInPool);
if(pthread_create(tid,NULL,ThreadRun,(void *)(&slaverSockManager))!=0)
{
return -1;
}
if(pthread_create(tid+1,NULL,ThreadRun,(void *)(&clientSockManager))!=0)
{
return -2;
}
if(pthread_create(tid+2,NULL,RunSendMsgThread,NULL)!=0)
{
return -3;
}
for(i=0;i<3;i++)
{
pthread_join(tid[i],NULL);
}
free(tid);
return 0;
}
//////////////////////////////////////////////////头文件////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
#include <netinet/in.h>
/*
* Copyright (C) 2013 yangguo <yangguo@yangguo-ubuntu 12.4LTS>
*******************************************************************
* project name:myClusterService
* Function:
*******************************************************************
* created time:2013-08-19-11.16
* company:dbc.ltd
* version:1.0
*******************************************************************
* support email:guoyang2011@gmail.com
* main function:服务端与slaver节点通信sock套接字池维护
* modify information:None
*******************************************************************
*/
/*******************************server与slaver端公用数据**********************/
//服务器、客户端、节点服务器之间通信的基本数据类型
struct ExchangeDataType
{
int Type;//传输数据类型
char baseData[1020];//范数据类型
};
/********************************End*******************************************/
/***************************公用数据类型Slaver端******************************/
//数据链表存储
struct SlaverTransDataType
{
struct SlaverTransDataType *next;
struct ExchangeDataType data;
};
/******************************************************************************/
/**************************公用数据类型server端********************************/
struct ClientSockInfoType
{
int c_sockfd;
struct sockaddr c_addr;
};
typedef struct BaseSockInfo//Epoll中监听套接字数据结构
{
struct BaseSockInfo *c_next;
struct ClientSockInfoType c_Info;
}SockInfo;
typedef struct BaseEpollSockInfo//Epoll配置基本信息数据结构
{
int epollSockfd;
int mainSockfd;
int listenSize;
int sockPort;
int eventListenSize;
char addr[50];
}EpollSockInfo;
typedef struct SockResourcePool//服务器端(Master端)Epoll管理链表基本数据结构
{
int slaverSockNum;
SockInfo *c_header;
EpollSockInfo serverInfo;
pthread_rwlock_t rwlock;
}SockInfoPool;
struct MasterTransDataType//服务器端(Master)收发数据链表数据结构
{
struct MasterTransDataType *next;
struct ExchangeDataType data;
struct ClientSockInfoType c_info;
};
/******************************************************************************/
//初始化通信模块函数
/*
slaverListenPort:监听节点服务器的公认端口号
clientListenPort:监听客户端的公认端口号
addr:服务器端监听IP地址
*/
int RunListen(const int slaverListenPort,const int clientListenPort,const char *addr);
/*
*/
struct MasterTransDataType *GetTaskFromInPool();
void freeInResource(struct MasterTransDataType *freeValue);
struct MasterTransDataType *MallocOutResource();
void AddTaskToOutPool(const struct MasterTransDataType *value);
InterCommunicationServerModelV1.0
最新推荐文章于 2019-10-21 16:06:53 发布