📄 tcpserver.cpp
字号:
}
return ret;
}
#endif
/*
****************************************************************************
* *
* Function Name : Write() *
* Description : To send a content buffer. *
* Parameter(s) : @fd : The associated socket. *
* @buf : A pointer to which the content is stored. *
* @len : The length of the buffer. *
* Return : @>0 : The bytes of send is returned. *
* @-1 : Failure. *
* *
****************************************************************************
*/
#ifdef __linux
__int32_t CTcpServer::Write(int fd, void *buf, __u_int len)
{
__int32_t ret = 0;
ret = send(fd, buf, len, 0);
if (ret < 0)
{
DBG("CTcpServer::Write() send error!\n");
return -1;
}
return ret;
}
#endif
/*
****************************************************************************
* *
* Function Name : Read() *
* Description : To receive a content buffer from a socket. *
* Parameter(s) : @fd : The associated socket. *
* @buf : A pointer to which the content will be stored. *
* @len : The length of the buffer. *
* Return : @>0 : The bytes of read is returned. *
* @ 0 : The peer has been shut down. *
* @-1 : Failure. *
* *
****************************************************************************
*/
#ifdef WIN32
__int32_t CTcpServer::Read(SOCKET fd, void *buf, __u_int len)
{
__int32_t ret = 0;
ret = recv(fd, reinterpret_cast<char *>(buf), len, 0);
if (ret == SOCKET_ERROR)
{
DBG("CTcpServer::Read() receive error!\n");
return -1;
}
return ret;
}
#endif
/*
****************************************************************************
* *
* Function Name : Write() *
* Description : To send a content buffer. *
* Parameter(s) : @fd : The associated socket. *
* @buf : A pointer to which the content is stored. *
* @len : The length of the buffer. *
* Return : @>0 : The bytes of send is returned. *
* @-1 : Failure. *
* *
****************************************************************************
*/
#ifdef WIN32
__int32_t CTcpServer::Write(SOCKET fd, void *buf, __u_int len)
{
__int32_t ret = 0;
ret = send(fd, reinterpret_cast<char *>(buf), len, 0);
if (ret == SOCKET_ERROR)
{
DBG("CTcpServer::Write() send buffer error!\n");
return -1;
}
return ret;
}
#endif
/*
****************************************************************************
* *
* Function Name : Init() *
* Description : To initialize the tcp server for listening. *
* Parameter(s) : None. *
* Return : @ 0 : success. *
* @-1 : failure. *
* *
****************************************************************************
*/
int CTcpServer::Init(void)
{
int ret = 0;
#ifdef WIN32
WinVersion = MAKEWORD(2, 2);
if (WSAStartup(WinVersion, &wsa) < 0)
{
DBG("TcpServer::Init() WSAStartup failure!\n");
return -1;
}
#endif
sock = socket(AF_INET, SOCK_STREAM, 0);
#ifdef __linux
if (sock < 0)
#else
if (sock == INVALID_SOCKET)
#endif
{
DBG("TcpServer::Init() create socket error!\n");
return -1;
}
int on = 1;
#ifdef __linux
ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (ret < 0)
#else
ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, \
reinterpret_cast<const char *>(&on), sizeof(on));
if (ret == SOCKET_ERROR)
#endif
{
DBG("TcpServer::Init() setsockopt() error!\n");
return -1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
ret = bind(sock, (struct sockaddr *)(&addr), sizeof(addr));
#ifdef __linux
if (ret < 0)
#else
if (ret == SOCKET_ERROR)
#endif
{
DBG("TcpServer::Init() bind error!\n");
return -1;
}
ret = listen(sock, 10);
#ifdef __linux
if (ret < 0)
#else
if (ret == SOCKET_ERROR)
#endif
{
DBG("TcpServer::Init() listen error!\n");
return -1;
}
return ret;
}
/*
****************************************************************************
* *
* Function Name : WorkerThread() *
* Description : The worker thread begin to carry out the task by calling*
* the virtual function which will be implemented by the *
* derived class. *
* Parameter(s) : @ A pointer to a struct of ThreadPack. *
* Return : NULL pointer. *
* *
****************************************************************************
*/
#ifdef __linux
void* CTcpServer::WorkerThread(void *arg)
{
pthread_detach(pthread_self());
ThreadPack *pArg = reinterpret_cast<ThreadPack *>(arg);
CTcpServer *pServer = reinterpret_cast<CTcpServer *>(pArg->obj);
int fd = pArg->pt;
struct sockaddr_in peer = pArg->addr;
pServer->Engine(fd, peer);
free(pArg);
return NULL;
}
#endif
#ifdef WIN32
DWORD CTcpServer::WorkerThread(LPVOID arg)
{
ThreadPack *pArg = reinterpret_cast<ThreadPack *>(arg);
CTcpServer *pServer = reinterpret_cast<CTcpServer *>(pArg->obj);
SOCKET fd = pArg->pt;
struct sockaddr_in peer = pArg->addr;
pServer->Engine(fd, peer);
free(pArg);
return 0;
}
#endif
/*
****************************************************************************
* *
* Function Name : ListenThread() *
* Description : To listen the public service port and then deliver it to*
* the worker thread. *
* Parameter(s) : @ arg : A pointer to the object of TcpServer. *
* Return : NULL pointer. *
* *
****************************************************************************
*/
#ifdef __linux
void* CTcpServer::ListenThread(void *arg)
{
CTcpServer *pServer = reinterpret_cast<CTcpServer *>(arg);
int ret = 0;
fd_set read_set;
struct timeval tv;
memset(&tv, 0, sizeof(tv));
tv.tv_sec = WAIT_TIME;
tv.tv_usec = 0;
while (!pServer->over)
{
struct sockaddr_in peer;
int len = sizeof(peer);
FD_ZERO(&read_set);
FD_SET(pServer->sock, &read_set);
ret = select(pServer->sock + 1, &read_set, NULL, NULL, &tv);
if (ret < 0)
{
DBG("CTcpServer::ListenThread select() error!\n");
continue;
}
if (ret == 0)
{ /* need to check the flag of over */
continue;
}
int fd = accept(pServer->sock, (struct sockaddr *)(&peer), \
(socklen_t *)(&len));
if (fd < 0)
{
DBG("CTcpServer::ListenThread() accept error\n");
DBG("Continue to listen!\n");
continue;
}
ThreadPack *pTmp = (ThreadPack *)malloc(sizeof(ThreadPack));
pTmp->obj = arg;
pTmp->pt = fd;
memmove(&(pTmp->addr), &peer, sizeof(peer));
pthread_t self;
pthread_create(&self, NULL, WorkerThread, \
reinterpret_cast<void *>(pTmp));
}
return NULL;
}
#endif
#ifdef WIN32
DWORD CTcpServer::ListenThread(LPVOID arg)
{
CTcpServer *pServer = reinterpret_cast<CTcpServer *>(arg);
int ret = 0;
fd_set read_set;
struct timeval tv;
memset(&tv, 0, sizeof(tv));
tv.tv_sec = WAIT_TIME;
tv.tv_usec = 0;
while (!pServer->over)
{
struct sockaddr_in peer;
int len = sizeof(peer);
FD_ZERO(&read_set);
FD_SET(pServer->sock, &read_set);
ret = select(0, &read_set, NULL, NULL, &tv);
if (ret == SOCKET_ERROR)
{
DBG("CTcpServer:;ListenThread() select error!\n");
continue;
}
if (ret == 0)
{ /* need to check the flag of over */
continue;
}
SOCKET fd = accept(pServer->sock, (struct sockaddr *)(&peer), &len);
if (fd == INVALID_SOCKET)
{
DBG("CTcpServer::ListenThread() accept error\n");
DBG("Continue to listen!\n");
continue;
}
ThreadPack *pTmp = (ThreadPack *)malloc(sizeof(ThreadPack));
pTmp->obj = arg;
pTmp->pt = fd;
memmove(&(pTmp->addr), &peer, sizeof(peer));
HANDLE hdl;
DWORD self;
hdl = CreateThread(NULL, 0, WorkerThread, \
reinterpret_cast<LPVOID>(pTmp), 0, &self);
if (hdl)
{
DBG("CTcpServer::ListenThread() Create worker thread success!\n");
}
else
{
DBG("CTcpServer::ListenThread() Fail to create worker thread!\n");
}
}
return 0;
}
#endif
/* The end */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -