- .h文件:
- #ifndef _TCPSERVER_H_
- #define _TCPSERVER_H_
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <list>
- #include <signal.h>
- #include <pthread.h>
- #include<stdlib.h>
- #include<stdio.h>
- #include"Log.h"
- using namespace std ;
- #define MAX_THREAD_COUNT 2500
- #define NT_MAX_DATA_LEN 256
- #define NT_IP_LEN 32
- typedef unsigned long ULONG;
- typedef unsigned short USHORT;
- typedef unsigned long int DWORD;
- typedef struct tagClientData
- {
- int socket;
- char ip[NT_IP_LEN];
- USHORT port;
- }ClientData, *pClientData;
- typedef struct tagServerData
- {
- char data[NT_MAX_DATA_LEN];
- int length;
- ClientData clientData;
- }ServerData, *pServerData;
- //回调函数的指针格式定义
- typedef void (*pServerDataCallback)(char* buf, int len, ClientData clientData, void* pUserdata);
- class TCPServer
- {
- public:
- TCPServer();
- ~TCPServer();
- bool Initialize(ushort recvPort, ULONG recvFunc, void* pUserdata);
- void Cleanup();
- bool SendData(char *sendData, int len, int socket);
- bool DisconnectClient(int client);
- public:
- void* m_clientOfflineUserdata;
- void* m_initUserdata;
- protected:
- bool m_isOperate;
- pthread_mutex_t cs_msg;
- pthread_mutex_t cs_accept;
- int m_socket;
- pthread_t m_hAccept;
- pthread_t m_hManage;
- list<int> m_clientList;
- list<ClientData> m_acceptList;
- list<ServerData> m_dataList;
- pServerDataCallback m_pCallBack;
- long m_lThreadCount;
- static void* AcceptThread(void* param);
- static void* RecvThread(void* param);
- static void* OperateThread(void* param);
- static void* ManageThread(void* param);
- };
- #endif
- cpp文件:
- #include "TCPServer.h"
- #define MAX_MSG_COUNT 5
- TCPServer::TCPServer()
- :m_clientOfflineUserdata(NULL),m_initUserdata(NULL),
- m_isOperate(false),m_clientList()
- ,m_acceptList(),m_dataList(),m_pCallBack(NULL)
- {
- pthread_mutex_init(&cs_msg,0);
- pthread_mutex_init(&cs_accept,0);
- m_socket = 0;
- m_hAccept = 0;
- m_hManage = 0;
- m_isOperate = false;
- m_lThreadCount = 0;
- m_pCallBack = NULL;
- }
- TCPServer::~TCPServer()
- {
- Cleanup();
- pthread_mutex_destroy(&cs_msg);
- pthread_mutex_destroy(&cs_accept);
- close(m_socket);
- }
- bool TCPServer::Initialize(USHORT recvPort, ULONG recvFunc, void* pUserdata)
- {
- if(pUserdata != NULL)
- {
- m_initUserdata = pUserdata;
- }
- m_pCallBack = (pServerDataCallback)recvFunc;
- Cleanup();
- m_socket = socket(AF_INET, SOCK_STREAM,0);
- if(m_socket<0)
- {
- return false;
- }
- struct sockaddr_in addrSrv;
- addrSrv.sin_addr.s_addr=htonl(INADDR_ANY);
- addrSrv.sin_family=AF_INET;
- addrSrv.sin_port=htons(recvPort);
- if(bind(m_socket,(struct sockaddr*)&addrSrv,sizeof(struct sockaddr))<0)
- {
- return false;
- }
- if (listen(m_socket, SOMAXCONN) == -1)
- {
- return false;
- }
- pthread_create(&m_hManage,0,ManageThread,this);
- if(m_hManage == 0)
- {
- return false;
- }
- pthread_create(&m_hAccept, 0,AcceptThread,this);
- if(m_hAccept == 0)
- {
- return false;
- }
- m_isOperate = true;
- return true;
- }
- void* TCPServer::AcceptThread(void* param)
- {
- sockaddr_in clientAddr;
- int nLen = sizeof(struct sockaddr);
- TCPServer* pMain = (TCPServer*)param;
- ClientData clientData = {0};
- while(1)
- {
- int dataSock = accept(pMain->m_socket, (struct sockaddr*) &clientAddr, (socklen_t*)&nLen);
- if(dataSock>0)
- {
- clientData.socket = dataSock;
- sprintf(clientData.ip, inet_ntoa(clientAddr.sin_addr));
- clientData.port = clientAddr.sin_port;
- pthread_mutex_lock(&pMain->cs_accept);
- (pMain->m_acceptList).push_back(clientData);
- pthread_mutex_unlock(&pMain->cs_accept);
- pthread_attr_t attr;
- pthread_attr_init (&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- pthread_t threadHandle;
- pthread_create(&threadHandle, &attr,RecvThread,param);
- pthread_attr_destroy (&attr);
- }
- }
- return 0;
- }
- void* TCPServer::RecvThread(void* param)//wsy
- {
- TCPServer* pMain = (TCPServer*)param;
- ServerData recvData;
- pthread_mutex_lock(&pMain->cs_accept);
- if((pMain->m_acceptList).size() > 0)
- {
- recvData.clientData = (pMain->m_acceptList).front();
- (pMain->m_acceptList).pop_front();
- (pMain->m_clientList).push_back(recvData.clientData.socket);
- pthread_mutex_unlock(&pMain->cs_accept);
- }
- else
- {
- pthread_mutex_unlock(&pMain->cs_accept);
- return 0;
- }
- while(1)
- {
- recvData.length = recv(recvData.clientData.socket, (char*)recvData.data, NT_MAX_DATA_LEN, 0);
- if(recvData.length != -1 && recvData.length != 0)
- {
- pthread_mutex_lock(&pMain->cs_msg);
- (pMain->m_dataList).push_back(recvData);
- pthread_mutex_unlock(&pMain->cs_msg);
- }
- else
- {
- close(recvData.clientData.socket);
- pthread_mutex_lock(&pMain->cs_accept);
- (pMain->m_clientList).remove(recvData.clientData.socket);
- pthread_mutex_unlock(&pMain->cs_accept);
- break;
- }
- }
- return 0;
- }
- void* TCPServer::OperateThread(void* param)
- {
- std::list<ServerData> ::size_type iCount=0;
- TCPServer* pMain = (TCPServer*)param;
- while(1)
- {
- pthread_mutex_lock(&pMain->cs_msg);
- if(!pMain->m_dataList.empty())
- {
- ServerData temp = (pMain->m_dataList).front();
- (pMain->m_dataList).pop_front();
- iCount = pMain->m_dataList.size();
- pthread_mutex_unlock(&pMain->cs_msg);
- int n=iCount/MAX_MSG_COUNT;
- while(n>0 && pMain->m_lThreadCount < MAX_THREAD_COUNT)
- {
- pthread_attr_t attr;
- pthread_attr_init (&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- pthread_t threadHandle;
- pthread_create(&threadHandle, &attr,OperateThread,pMain);
- pthread_attr_destroy (&attr);
- pMain->m_lThreadCount++;
- n--;
- }
- if(pMain->m_pCallBack != NULL)
- {
- pMain->m_pCallBack(temp.data, temp.length, temp.clientData, pMain->m_initUserdata);
- }
- }
- else
- {
- pthread_mutex_unlock(&pMain->cs_msg);
- break;
- }
- }
- pMain->m_lThreadCount--;
- return 0;
- }
- void* TCPServer::ManageThread(void* param)
- {
- std::list<ServerData> ::size_type iCount=0;
- TCPServer* pMain = (TCPServer*)param;
- while(1)
- {
- pthread_mutex_lock(&pMain->cs_msg);
- iCount = pMain->m_dataList.size();
- pthread_mutex_unlock(&pMain->cs_msg);
- if( iCount > 0)
- {
- pthread_attr_t attr;
- pthread_attr_init (&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- pthread_t threadHandle;
- pthread_create(&threadHandle, &attr,OperateThread,pMain);
- pthread_attr_destroy (&attr);
- }
- sleep(1);
- }
- return 0;
- }
- bool TCPServer::SendData(char *sendData, int len, int socket)
- {
- int ret = 0;
- if(socket != 0)
- {
- ret = send(socket, (char*)sendData, len,0);
- if(ret == -1)
- {
- pthread_mutex_lock(&cs_accept);
- (m_clientList).remove(socket);
- pthread_mutex_unlock(&cs_accept);
- return false;
- }
- }
- else
- {
- for(list<int>::iterator i = m_clientList.begin(); i != m_clientList.end();)
- {
- list<int>::iterator temp = i++;
- if(-1 == send(*temp, (char*)sendData, len, 0))
- {
- pthread_mutex_lock(&cs_accept);
- m_clientList.erase(temp);
- pthread_mutex_unlock(&cs_accept);
- }
- }
- }
- return true;
- }
- void TCPServer::Cleanup()
- {
- DWORD exitCode = 0;
- m_isOperate = false;
- if(m_hAccept != 0)
- {
- pthread_cancel(m_hAccept);
- m_hAccept = 0;
- }
- if(m_socket != 0)
- {
- close(m_socket);
- m_socket = 0;
- }
- for(list<int>::iterator i = m_clientList.begin(); i != m_clientList.end(); i++)
- {
- close(*i);
- }
- pthread_mutex_lock(&cs_accept);
- m_clientList.clear();
- pthread_mutex_unlock(&cs_accept);
- if(m_hManage != 0)
- {
- pthread_cancel(m_hManage);
- m_hManage = 0;
- }
- }
- bool TCPServer::DisconnectClient(int client)
- {
- pthread_mutex_lock(&cs_accept);
- m_clientList.remove(client);
- pthread_mutex_unlock(&cs_accept);
- return close(client);
- }
- //该片段来自于http://www.codesnippet.cn/detail/1504201512264.html
来源: http://www.codesnippet.cn/detail/1504201512264.html