abstractserver.cpp

#define TCP 0
#define UDP 1
#define THREAD_STACK_SIZE 1*1024*1024


//using namespace std
//using  std::string;
typedef struct client_t
{
int sockfd;
}myclient;
class abstractserver
{
public:
int  msockfd;//server sockfd
int mserverport;
int mtimeout;
int mtransmode;
char *mserverip;
char *mhostname;//域名
char *mclientip;
char *msendbuf;
char *mrecvbuf;
int  mNeedSend;//要发送的数据
int  mRecvBufLen;//接受缓冲区大小
//static void (*callbackserver) (void *argv);//服务器处理函数



public:
abstractserver(int port, char *serip, char *hostname,int t_mode);
virtual ~abstractserver(void);
bool init_socket();
void Close(int sockfd);
void SetBlock(bool bblock,int sockfd);
bool Checktimeout(bool isread,int sockfd);
bool AcceptClient(void);
int create_client_thread(myclient *m_client);
int SendData(int sockfd);
int RecvDate(int sockfd);
//static  void realthread(void *arg);
//virtual bool SendCommand(const char* szMessage)=0;


};


#include"common.h"
#include "abstractserver.h"

#if 0
#ifdef  __cplusplus
extern "C"{
#endif
extern void server_thread(void *argv);// in xxx.c file


#ifdef  __cplusplus
}
#endif
#else
extern void server_thread(void *argv);// in xxx.cpp file
#endif

 void  *realthread(void *arg)
{
server_thread(arg);
return (void *)NULL;
}


// this is a tcp server demo
abstractserver::abstractserver(int port, char *serip,char *hostname, int t_mode)
{
mserverport = port;
mtransmode = t_mode;
mtimeout = 10;//10 sec
msockfd = -1;
mserverip = NULL;
mhostname = NULL;
mRecvBufLen = 0;
mNeedSend = 0;
msendbuf = NULL;
mrecvbuf = NULL;
if(serip!=NULL)
{

mserverip = (char *)malloc(32);
if(mserverip)
{
snprintf(mserverip,32,"%s",serip);
}
}


if( hostname!=NULL)
{
mhostname = (char *)malloc(128);
if(mhostname)
{
snprintf(mhostname,128,"%s",hostname);
}
}

}


abstractserver::~abstractserver(void)
{
if(mserverip!=NULL)
{
free((void *)mserverip);
}
if(mhostname!=NULL)
{
free((void *)mhostname);
}
//Close();
printf("release abstractclient !\n");
}

void abstractserver::Close(int sockfd)
{
#ifdef Linux
if(sockfd >= 0)
{
shutdown(sockfd,SHUT_WR);
close(sockfd);
}
#elif _WIN32_WINNT
if(sockfd >= 0)
{
shutdown(sockfd,SD_SEND);
closesocket(sockfd);
}
#endif


sockfd = -1;
}


//设置网络套接字阻塞或者非阻塞
void abstractserver::SetBlock(bool bblock,int sockfd)
{
#ifdef Linux
int mode = bblock ? 0 : 1;
ioctl(sockfd, FIONBIO, &mode); //设置为非阻塞模式
#elif _WIN32_WINNT
unsigned long op = bblock ? 0 : 1;
if (ioctlsocket(sockfd, FIONBIO, &op) == SOCKET_ERROR)
{
printf("Unable to Set Blocking");
}
#endif
}


//判断网络是否超时
bool abstractserver::Checktimeout(bool isread,int sockfd)
{
int len;
fd_set writeset;
fd_set readset;
fd_set *fdset = NULL;
struct timeval tm;
len = sizeof(int);
tm.tv_sec = mtimeout;
tm.tv_usec = 0;
FD_ZERO(&readset);
FD_ZERO(&writeset);

if(isread)
{

FD_SET(sockfd, &readset);
fdset = &readset;
}
else
{
FD_SET(sockfd, &writeset);
fdset = &writeset;
}


/* 等待连接,如果超时(10s),那么返回连接错误 by wangjidong*/
if (select(sockfd + 1,&readset,&writeset, NULL, &tm) > 0)
{
if(FD_ISSET(sockfd,fdset))
{
return false;
}
else
{
return true;
}

}
else
{
return true;   
}






return false;
}

// 初始化socket
bool abstractserver::init_socket()
{
if(mtransmode == UDP)
{
msockfd = socket(AF_INET, SOCK_DGRAM, 0);
}
else
{
msockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
}

if (0 > msockfd)
{
return false;
}

struct sockaddr_in server;     //服务器地址信息结构体
  memset(&server,0,sizeof(server));
server.sin_family=AF_INET;
server.sin_port=htons(mserverport);
server.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind(msockfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) 
{    //调用bind绑定地址
perror("Bind error.");
return false;
}   

if(listen(msockfd,10) == -1)
{      //调用listen开始监听
perror("listen() error\n");
return false;
}
unsigned int nBufferSize = 40960;
unsigned int nBufferSize2 = 40960;
int reuse = true;
setsockopt(msockfd, SOL_SOCKET, SO_SNDBUF, (char *)&nBufferSize2, sizeof(nBufferSize2));
setsockopt(msockfd, SOL_SOCKET, SO_RCVBUF, (char *)&nBufferSize, sizeof(nBufferSize));
setsockopt(msockfd,SOL_SOCKET ,SO_REUSEADDR,(char *)&reuse,sizeof(int));

/*设置socket 阻塞模式发送接收数据*/
//阻塞模式http 协议数据够用
SetBlock(true,msockfd);

return true;   
}


// try connect server ,first init sock, then connect server
bool abstractserver::AcceptClient(void)
{
if(init_socket()==false)
{
return false;
}
int clientfd;
struct sockaddr_in Clientaddr;
int sin_size = sizeof(Clientaddr);

while(1)
{
if(Checktimeout(true,msockfd))
{
printf("Checktimeout @@@ in AcceptClient\n");
continue;
}
if ((clientfd = accept(msockfd,(struct sockaddr *)&Clientaddr,(socklen_t *)&sin_size))== -1) 
{
printf("accept() error\n");
continue;
}
printf("accept a client is %s \n",inet_ntoa(Clientaddr.sin_addr));
myclient *m_client = (myclient *)malloc(sizeof(myclient));
if(m_client != NULL)
{
m_client->sockfd = clientfd;
create_client_thread(m_client);
}
else
{
Close(clientfd);
}

}

return true;

}

int abstractserver::create_client_thread(myclient *m_client)
{
if(m_client ==NULL )
{
return -1;
}
pthread_t tid;
pthread_attr_t attr;


pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);

//*callbackclient must free the client the struct*//
int ret = pthread_create(&tid, &attr, realthread,(void*) m_client);
if (ret != 0)   
{   
printf("create thread cloud_msg_handle_thread fail, ret %d \n", ret);



Close(m_client->sockfd);
if(m_client != NULL)
{
free((void *)m_client);
}
return -1;
}
return tid;
}


int abstractserver::SendData(int sockfd)
{
if(msendbuf == NULL || mNeedSend <= 0)
{
return -1;
}
bool is_read = false;


if(Checktimeout(is_read,sockfd))
{
return -1;
}
int ret = send(sockfd,msendbuf,mNeedSend,0);
// ret <= 0 is false 
mNeedSend = 0;
msendbuf = NULL;
return ret;

}


int abstractserver::RecvDate(int sockfd)
{
if(mrecvbuf == NULL || mRecvBufLen <= 0)
{
return -1;
}


bool is_read = true;


if(Checktimeout(is_read,sockfd))
{
return -1;
}

int ret = recv(sockfd,mrecvbuf,mRecvBufLen,0);
// ret <= 0 is false 
// 0 close 
// -1 network error

mRecvBufLen = 0;
mrecvbuf = NULL;
return ret;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值