⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpserver.cpp

📁 TCP的服务器与客户端基类
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#include "TcpServer.h"

/*
 ****************************************************************************
 *                         CLASS IMPLEMENTATION                             *
 ****************************************************************************
 */

/* For CTcpServer */

/*
 ****************************************************************************
 *                                                                          *
 *  Function Name : CTcpServer()                                            *
 *  Description   : The construction function.                              *
 *  Parameter(s)  : @pt : the public service port.                          *
 *  Return        : None.                                                   *
 *                                                                          *
 ****************************************************************************
 */
 
CTcpServer::CTcpServer(short pt) : port(pt), over(false)
{
    #ifdef __linux
    sock          = 0;
    listen_thread = 0;
    #endif
    #ifdef WIN32
    listen_thread = NULL;
    #endif
}

/*
 ****************************************************************************
 *                                                                          *
 *  Function Name : ~CTcpServer()                                           *
 *  Description   : The deconstruction function.                            *
 *  Parameter(s)  : None.                                                   *
 *  Return        : None.                                                   *
 *                                                                          *
 ****************************************************************************
 */

CTcpServer::~CTcpServer(void)
{
    this->over = true;
    #ifdef __linux
    if (listen_thread != 0)
    {
        pthread_join(listen_thread, NULL);
    }
    
    if (sock > 0)
    {
        close(sock);
    }
    #endif

    #ifdef WIN32
    if (listen_thread)
    {
        WaitForSingleObject(listen_thread, INFINITE);
	CloseHandle(listen_thread);
	listen_thread = NULL;
    }
    
    closesocket(sock);
    WSACleanup();
    #endif
}

/*
 ****************************************************************************
 *                                                                          *
 *  Function Name : NonBlockStart()                                         *
 *  Description   : To start the TCP server and create a new thread to      *
 *                  watch the public socket.                                *
 *  Parameter(s)  : None.                                                   *
 *  Return        : @ 0 : success.                                          *
 *                  @-1 : failure.                                          *
 *                                                                          *
 ****************************************************************************
 */

int CTcpServer::NonBlockStart(void)
{
    int ret = 0;

    ret = Init();
    if (ret < 0)
    {
        DBG("TcpServer::NonBlockStart() Init error!\n");
	return ret;
    }

    #ifdef __linux
    ret = pthread_create(&listen_thread, NULL, ListenThread, \
    		reinterpret_cast<void *>(this));
    #endif
    #ifdef WIN32
    DWORD  self;
    listen_thread = CreateThread(NULL, 0, ListenThread, \
    		reinterpret_cast<LPVOID>(this), 0, &self);
    if (listen_thread)
    {
        DBG("CTcpServer::NonBlockStart() Create listening thread success!\n");
    }
    else
    {
        DBG("CTcpServer::NonBlockStart() Create thread failed!\n");
	ret = -1;
    }
    #endif

    return ret;
}

/*
 ****************************************************************************
 *                                                                          *
 *  Function Name : BlockStart()                                            *
 *  Description   : To start the TCP server, there is no thread would be    *
 *                  created to listen the public port. Instead, the main    *
 *                  thread will do it by itself.                            *
 *  Parameter(s)  : None.                                                   *
 *  Return        : @ 0 : success.                                          *
 *                  @-1 : failure.                                          *
 *                                                                          *
 ****************************************************************************
 */

int CTcpServer::BlockStart(void)
{
    int ret = 0;

    ret = Init();
    if (ret < 0)
    {
        DBG("CTcpServer::BlockStart() Init error!\n");
	return ret;
    }

    fd_set read_set;
    struct timeval tv;
    memset(&tv, 0, sizeof(tv));

    tv.tv_sec  = WAIT_TIME;
    tv.tv_usec = 0;

    while (!over)
    {
        struct sockaddr_in peer;
	int    len = sizeof(peer);
        #ifdef __linux
        FD_ZERO(&read_set);
        FD_SET(sock, &read_set);
	
	ret = select(sock + 1, &read_set, NULL, NULL, &tv);
	if (ret < 0)
	{
	    DBG("CTcpServer::BlockStart select() error!\n");
	    continue;
	}

	if (ret == 0)
	{   /* need to check the flag of over */
	    continue;
	}

	int fd = accept(sock, (struct sockaddr *)(&peer), \
			(socklen_t *)(&len));
	if (fd < 0)
	{
	    DBG("CTcpServer::BlockStart() accept error!\n");
	    DBG("Continue to listen!\n");
	    continue;
	}

	ThreadPack *pTem = (ThreadPack *)malloc(sizeof(ThreadPack));
	pTem->obj = this;
	pTem->pt  = fd;
	memmove(&(pTem->addr), &peer, sizeof(peer));
	

	pthread_t self;
	pthread_create(&self, NULL, WorkerThread, \
			reinterpret_cast<void *>(pTem));
	#endif

	#ifdef WIN32
	FD_ZERO(&read_set);
	FD_SET(sock, &read_set);

	ret = select(0, &read_set, NULL, NULL, &tv);
	if (ret == SOCKET_ERROR)
	{
	    DBG("CTcpServer::BlockStart select() error!\n");
	    continue;
	}

	if (ret == 0)
	{   /* need to check the flag of over */
	    continue;
	}
	
	SOCKET fd = accept(sock, (struct sockaddr *)(&peer), &len);
	if (fd == INVALID_SOCKET)
	{
	    DBG("CTcpServer::BlockStart() accept() error!\n");
	    DBG("Continue to listen!\n");
	    continue;
	}
	
	ThreadPack *pTem = (ThreadPack *)malloc(sizeof(ThreadPack));
	pTem->obj = this;
	pTem->pt  = fd;
	memmove(&(pTem->addr), &peer, sizeof(peer));

	HANDLE hdl;
	DWORD  self;
	hdl = CreateThread(NULL, 0, WorkerThread, \
			reinterpret_cast<LPVOID>(pTem), 0, &self);
        if (hdl)
	{
	    DBG("CTcpServer::BlockStart() Create worker thread success!\n");
	}
	else 
	{
	    DBG("CTcpServer::BlockStart() Fail to create worker thread!\n");
	}
	#endif
    }

    return ret;
}

/*
 ****************************************************************************
 *                                                                          *
 *  Function Name : Stop()                                                  *
 *  Description   : To stop the listening service.                          *
 *  Parameter(s)  : None.                                                   *
 *  Return        : @ 0 : success.                                          *
 *                                                                          *
 ****************************************************************************
 */

int CTcpServer::Stop(void)
{
    this->over = true;
    #ifdef __linux
    if (listen_thread != 0)
    {
        pthread_join(listen_thread, NULL);
	listen_thread = 0;
    }

    if (sock > 0)
    {
        close(sock);
	sock = 0;
    }
    #endif

    #ifdef WIN32
    if (listen_thread)
    {
        WaitForSingleObject(listen_thread, INFINITE);
	CloseHandle(listen_thread);
	listen_thread = NULL;
    }

    closesocket(sock);
    WSACleanup();
    #endif
    this->over = false;
    
    return 0;
}

/*
 ****************************************************************************
 *                                                                          *
 *  Function Name : ReStart()                                               *
 *  Description   : To restart the TCP server.                              *
 *  Parameter(s)  :                                                         *
 *  Return        :                                                         *
 *                                                                          *
 ****************************************************************************
 */

int CTcpServer::ReStart(void)
{
    Stop();
    return this->NonBlockStart();
}

/*
 ****************************************************************************
 *                                                                          *
 *  Function Name : SetPort()                                               *
 *  Description   : To set the port number.                                 *
 *  Parameter(s)  : @pt : the desired port number.                          *
 *  Return        : None.                                                   *
 *                                                                          *
 ****************************************************************************
 */

void CTcpServer::SetPort(short pt)
{
    port = pt;
    return ;
}

/*
 ****************************************************************************
 *                                                                          *
 *  Function Name : GetPort()                                               *
 *  Description   : To get the port number.                                 *
 *  Parameter(s)  : @pt : a reference which receives the port number.       *
 *  Return        : None.                                                   *
 *                                                                          *
 ****************************************************************************
 */

void CTcpServer::GetPort(short &pt)
{
    pt = port;
    return ;
}

/*
 ****************************************************************************
 *                                                                          *
 *  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 shutdown.                      *
 *                  @-1  : Failure.                                         * 
 *                                                                          *
 ****************************************************************************
 */

#ifdef __linux
__int32_t CTcpServer::Read(int fd, void *buf, __u_int len)
{
    __int32_t ret = 0;

    ret = recv(fd, buf, len, 0);
    if (ret < 0)
    {
        DBG("CTcpServer::Read() receive error!\n");
	return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -