TCP完成端口服务器构建
版权声明:本文为博主原创文章,未经博主允许不得转载。
在vs2008中编译通过,vs2010应该也没有问题。
使用静态MFC dll。
其他配置保持默认即可。
可能需要设置/MTD运行时。
可以实现向指定客户端ip发送信息
(该客户端必须首先连接进服务器)
从指定客户端ip中取出数据。
我使用C++类进行了封装,
对各种异常进行了处理。
进行了较详细的注释,
如果有函数不清楚,可以去msdn上查一查。
1,客户端类
![](https://code.csdn.net/assets/CODE_ico.png)
- #pragma once
- #define RECEIVE_SIZE 1024
- /****************************************************
- //Client
- function :
- save info of client
- ***************************************************/
- class Client
- {
- public:
- Client();
- ~Client();
- public:
- CCriticalSection m_cs;
- BYTE m_pRemainBuf[RECEIVE_SIZE]; //数据缓存区
- BYTE m_nDataLen; //数据缓冲区中已有数据的长度
- BYTE m_pReceBuf[RECEIVE_SIZE]; //接受到的数据
- OVERLAPPED m_OverLapped;
- WSABUF m_DataBuf;
- SOCKADDR_IN m_ClientAddress;
- //[!if NET_TYPE_TCP]
- SOCKET m_hClientSock; //communication socket;
- //[!endif]
- public:
- //***********将数据存入Client对应的缓冲区中*******************
- BOOL SetData(int len);
- //***********从Client对应的缓冲区中取出数据*******************
- int GetData(char * buff, int len);
- };
实现:
![](https://code.csdn.net/assets/CODE_ico.png)
- #include "stdafx.h"
- #include "Client.h"
- /****************************************************************************
- * Name
- Client
- * Type
- public
- * Function
- construction function
- * Return Value
- null
- * Parameters
- null
- *****************************************************************************/
- Client::Client()
- {
- //[!if NET_TYPE_TCP]
- m_hClientSock = INVALID_SOCKET;
- //[!endif]
- m_nDataLen = 0;
- memset(m_pRemainBuf, 0, RECEIVE_SIZE);
- memset(m_pReceBuf,0,RECEIVE_SIZE);
- memset(&m_OverLapped, 0, sizeof(m_OverLapped));
- }
- /****************************************************************************
- * Name
- ~Client
- * Type
- public
- * Function
- * Return Value
- null
- * Parameters
- null
- *****************************************************************************/
- Client::~Client()
- {
- int a=0;
- a=3;
- }
- //*********************TCP接受数据************************
- //**************缓冲区没有溢出,则将数据追加其后**********
- BOOL Client::SetData( int len )
- {
- if (len<0)
- {
- return FALSE;
- }
- if (len==0)
- {
- return TRUE;
- }
- m_cs.Lock();
- if (m_nDataLen+len>=RECEIVE_SIZE)
- {
- if (len<RECEIVE_SIZE)
- {
- memcpy_s(m_pRemainBuf, RECEIVE_SIZE, m_pReceBuf, len);
- m_nDataLen = len;
- }
- else
- {
- memcpy_s(m_pRemainBuf, RECEIVE_SIZE, m_pReceBuf, RECEIVE_SIZE);
- m_nDataLen = (BYTE)RECEIVE_SIZE;
- }
- }
- else
- {
- memcpy_s(m_pRemainBuf + m_nDataLen, RECEIVE_SIZE-m_nDataLen, m_pReceBuf, len);
- m_nDataLen += len;
- }
- m_cs.Unlock();
- return TRUE;
- }
- int Client::GetData( char * buff, int len )
- {
- if (!buff)
- {
- return 0;
- }
- int result=0;
- m_cs.Lock();
- if (m_nDataLen <= len)
- {
- memcpy_s(buff, len, m_pRemainBuf, m_nDataLen);
- result = m_nDataLen;
- m_nDataLen = 0;
- }
- else
- {
- memcpy_s(buff, len, m_pRemainBuf, len);
- memmove_s(m_pRemainBuf, RECEIVE_SIZE, m_pRemainBuf + len, m_nDataLen-len);
- m_nDataLen -= len;
- result = len;
- }
- m_cs.Unlock();
- return result;
- }
2,TCP完成端口的封装
头文件:
![](https://code.csdn.net/assets/CODE_ico.png)
- /************************************************************************/
- //* 文件名称: IOCP_TCP.h
- //* 文件标示:
- //* 摘 要:采用完成端口技术处理网络数据
- //*
- //* 当前版本:1.0
- //* 作 者:hxy
- //* 完成日期:2013-11-16
- //*
- /************************************************************************/
- #ifndef _COMPLETIONPORT_H__
- #define _COMPLETIONPORT_H__
- #include <winsock2.h>
- #include <mswsock.h>
- #include "afxmt.h"
- #include <vector>
- #include "Client.h"
- using namespace std;
- #pragma once
- #define MAXTHREAD_COUNT 8
- #define RECEIVE_SIZE 1024
- #define PORT 502
- class Client;
- class CompletionPort
- {
- public:
- CompletionPort();
- ~CompletionPort();
- //************初始化****************************
- // 参数: 需要绑定的ip和port
- // 功能: 初始化socket库
- // 设置需要绑定的ip和port
- //**********************************************
- BOOL Init(char * lpszHostAddress, UINT nHostPort);
- //************启动******************************
- // 功能: 1,启动监听功能; 2,生成完成端口对象
- //**********************************************
- BOOL Active(void);
- //************停止******************************
- // 功能: 停止监听功能,
- // 释放Active中的申请的所有资源
- //**********************************************
- BOOL Close(void);
- //************接受数据**************************
- // 功能: 接受指定客户端ip的数据
- // 参数: buff:指向接受数据的缓冲区
- // len: 缓冲区的大小
- // ip: 客户端ip,如192.168.31.27
- // 说明: buff的内存由调用者提供
- //**********************************************
- int ReceiveData(char * buff, int len, char * ip);
- //************发送数据***************************
- // 功能: 向指定的客户端ip的数据
- // 参数: buff:指向发送数据的缓冲区
- // len: 缓冲区的大小
- // ip: 客户端ip,如192.168.31.27
- //**********************************************
- int SendData(const char * buff, int len, char * ip);
- //-------------------------内部使用--------------------------------
- //************监听*******************************
- // 功能: 监听客户端连接线程
- //***********************************************
- void MonitorServerSocket();
- //************监听客户端发送的数据***************
- // 功能: 监听客户端连接线程函数
- //***********************************************
- void MonitorIoCompletionPort();
- //************处理客户端连接*********************
- // 功能: 客户端连接处理函数
- //***********************************************
- void OnClientAccept();
- //************处理客户端关闭*********************
- // 功能: 客户端关闭处理函数
- //***********************************************
- BOOL OnClientClose(DWORD dwSockId);
- private:
- //************初始化Socket库*********************
- // 功能: 初始化Socket库
- //***********************************************
- BOOL InitWinsock();
- void ProcessData(Client* pClient);
- Client* GetClient(DWORD dwSockId, int& index);
- //----------------------------Client 管理-------------------------
- //************增加客户端*********************
- BOOL AddClient( Client * const pClient);
- //************删除客户端*********************
- BOOL DeleteClient( int index);
- //************查询客户端*********************
- Client * GetClient( const char * ip);
- private:
- SOCKADDR_IN m_HostAddress; //服务器端地址(ip,port,协议)等
- vector<Client*> m_ClientVector; //客户端表
- rec_lock m_cs; //客户端表同步
- BOOL m_bIsQuit; //退出标识
- HANDLE m_hQuitEvent; //退出事件句柄
- HANDLE m_hCOP; //完成端口句柄
- HANDLE m_hThreadArray[MAXTHREAD_COUNT]; //接收数据线程句柄
- int m_nThreadArray; //接收数据线程数量
- HANDLE m_hListen; //监听连接线程句柄
- SOCKET m_ListenSocket; //监听socket
- BOOL m_bQuitThread; //监听线程退出标识
- WSAEVENT m_wsaEvent; //网络事件
- };
- #endif
实现文件:
![](https://code.csdn.net/assets/CODE_ico.png)
- #include "StdAfx.h"
- #include "IOCP_TCP.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /****************************************************************************
- * Name
- ThreadTcpServer
- * Type
- public
- * Function
- thread to monitor a socket and accept a link
- * Return Value
- DWORD WINAPI
- * Parameters
- void * lpParameter
- *****************************************************************************/
- DWORD WINAPI ThreadTcpServer(void * lpParameter)
- {
- CompletionPort* pCpPort = (CompletionPort*)lpParameter;
- pCpPort->MonitorServerSocket();
- return 0;
- }
- /****************************************************************************
- * Name
- CompletionRoutine
- * Type
- public
- * Function
- work thread of completionport
- * Return Value
- DWORD WINAPI
- * Parameters
- void * lpParameter translate a pointer of this
- *****************************************************************************/
- DWORD WINAPI CompletionRoutine(void * lpParameter)
- {
- CompletionPort* pCpPort = (CompletionPort*)lpParameter;
- pCpPort->MonitorIoCompletionPort();
- return 0;
- }
- /****************************************************************************
- * Name
- CompletionPort
- * Type
- public
- * Function
- constructor
- * Return Value
- null
- * Parameters
- null
- *****************************************************************************/
- CompletionPort::CompletionPort()
- {
- //_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF| _CRTDBG_LEAK_CHECK_DF);
- m_hCOP = INVALID_HANDLE_VALUE;
- m_hListen = INVALID_HANDLE_VALUE;
- for (int i=0; i< MAXTHREAD_COUNT; i++)
- {
- m_hThreadArray[i] = INVALID_HANDLE_VALUE;
- }
- m_bQuitThread = FALSE;
- m_wsaEvent = NULL;
- m_ListenSocket = INVALID_SOCKET;
- m_ClientVector.clear();
- m_bIsQuit = FALSE;
- m_hQuitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- m_nThreadArray = 0;
- }
- /****************************************************************************
- * Name
- ~CompletionPort
- * Type
- public
- * Function
- do sth to release memory
- * Return Value
- null
- * Parameters
- null
- *****************************************************************************/
- CompletionPort::~CompletionPort()
- {
- int i = 0;
- m_bIsQuit = TRUE;
- Sleep(10);
- if (INVALID_HANDLE_VALUE != m_hCOP)
- {
- m_bIsQuit = TRUE;
- //等待所有接受数据的线程结束
- WaitForMultipleObjects(m_nThreadArray, m_hThreadArray, TRUE, INFINITE);
- while (INVALID_HANDLE_VALUE != m_hThreadArray[i])
- {
- CloseHandle(m_hThreadArray[i]);
- m_hThreadArray[i-1] = INVALID_HANDLE_VALUE;
- i++;
- }
- //关闭完成端口
- CloseHandle(m_hCOP);
- m_hCOP=NULL;
- }
- // 关闭监听socket
- if (INVALID_SOCKET != m_ListenSocket)
- {
- closesocket(m_ListenSocket);
- m_ListenSocket = NULL;
- }
- // 关闭监听线程
- m_bQuitThread = TRUE;
- WaitForSingleObject(m_hListen, INFINITE);
- if (INVALID_HANDLE_VALUE != m_hListen)
- {
- CloseHandle(m_hListen);
- m_hListen = NULL;
- }
- WSACloseEvent(m_wsaEvent);
- m_wsaEvent = NULL;
- // 关闭客户端连接socket
- for( size_t i=0; i<m_ClientVector.size(); i++)
- {
- Client* pClient = m_ClientVector[i];
- if( pClient != NULL)
- {
- if (pClient->m_hClientSock != INVALID_SOCKET)
- {
- shutdown(pClient->m_hClientSock, 2);
- closesocket(pClient->m_hClientSock);
- pClient->m_hClientSock = INVALID_SOCKET;
- }
- delete pClient;
- pClient = NULL;
- }
- }
- CloseHandle(m_hQuitEvent);
- m_ClientVector.clear();
- }
- BOOL CompletionPort::Init(char * lpszHostAddress, UINT nHostPort)
- {
- if (!InitWinsock())
- {
- return FALSE;
- }
- m_HostAddress.sin_family = AF_INET;
- m_HostAddress.sin_addr.s_addr = inet_addr((char *)lpszHostAddress);
- if (m_HostAddress.sin_addr.s_addr == INADDR_NONE)
- {
- LPHOSTENT lphost;
- lphost = gethostbyname((char *)lpszHostAddress);
- if (lphost != NULL)
- m_HostAddress.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
- else
- {
- WSASetLastError(WSAEINVAL);
- return FALSE;
- }
- }
- m_HostAddress.sin_port = htons((u_short)nHostPort);
- return true;
- }
- //************启动******************************
- // 功能: 启动监听功能
- //**********************************************
- BOOL CompletionPort::Active()
- {
- //-------------------------------监听连接---------------------------------------
- //创建监听Socket
- m_ListenSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
- if (INVALID_SOCKET == m_ListenSocket)
- {
- return FALSE;
- }
- int nResult = bind(m_ListenSocket, (PSOCKADDR)&m_HostAddress, sizeof(m_HostAddress));
- if (SOCKET_ERROR == nResult)
- {
- closesocket(m_ListenSocket);
- return FALSE;
- }
- nResult = listen(m_ListenSocket, 20);
- if (SOCKET_ERROR == nResult)
- {
- closesocket(m_ListenSocket);
- return FALSE;
- }
- m_wsaEvent = WSACreateEvent();
- if (NULL == m_wsaEvent)
- {
- return FALSE;
- }
- WSAEventSelect(m_ListenSocket, m_wsaEvent, FD_ACCEPT);
- //创建监听连接的线程
- m_hListen = CreateThread(NULL, 0, ThreadTcpServer, (LPVOID)this, 0, NULL);
- if (NULL == m_hListen)
- {
- return FALSE;
- }
- //-------------------------------完成端口---------------------------------------
- //创建完成端口句柄
- m_hCOP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0);
- if (NULL == m_hCOP)
- {
- return FALSE;
- }
- //创建处理数据的线程
- SYSTEM_INFO SysInfo;
- GetSystemInfo(&SysInfo);
- for (int i=0; i<(int)SysInfo.dwNumberOfProcessors && (i<MAXTHREAD_COUNT); i++)
- {
- m_hThreadArray[i] = CreateThread(NULL, 0, CompletionRoutine, (LPVOID)this, 0, NULL);
- if (NULL == m_hThreadArray[i])
- {
- while (i>0)
- {
- CloseHandle(m_hThreadArray[i-1]);
- m_hThreadArray[i-1] = INVALID_HANDLE_VALUE;
- i--;
- }
- return FALSE;
- }
- m_nThreadArray ++;
- }
- return TRUE;
- }
- //************从完成端口取数据******************
- // 功能: 从完成端口取数据
- // 返回: 字节数,如果ip未连接则返回0
- //**********************************************
- int CompletionPort::ReceiveData(char * buff, int len, char * ip)
- {
- if (!buff || !ip)
- {
- return 0;
- }
- Client * pClient = GetClient(ip);
- if (!pClient)
- {
- return 0;
- }
- return pClient->GetData(buff, len);
- }
- //************发送数据***************************
- // 功能: 向指定的客户端ip的数据
- // 参数: buff:指向发送数据的缓冲区
- // len: 要发送的数据的字节数
- // ip: 客户端ip,如192.168.31.27
- // 返回: 发送的字节数,错误则返回0
- //**********************************************
- int CompletionPort::SendData(const char * buff, int len, char * ip)
- {
- if (!buff || !ip)
- {
- return 0;
- }
- int ret =0;
- //在取得客户端指针之后,完成端口线程会删除该客户端,
- //可能造成最null指针的解引用,所有这里使用结构化异常进行处理
- __try
- {
- Client * pClient = GetClient(ip);
- if (!pClient)
- {
- return 0;
- }
- DWORD result = 0;
- ret =send(pClient->m_hClientSock, buff, len, 0);
- //int ret = WriteFile((HANDLE)pClient->m_hClientSock, buff, len, &result, NULL);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- printf("客户端已被删除,发送失败");
- }
- return ret;
- }
- /****************************************************************************
- * Name
- InitWinsock
- * Type
- public
- * Function
- initialize socket
- * Return Value
- BOOL
- * Parameters
- null
- *****************************************************************************/
- BOOL CompletionPort::InitWinsock()
- {
- WSADATA wsd;
- int nResult = WSAStartup(MAKEWORD(2,2), &wsd);
- if (0 != nResult)
- {
- return FALSE;
- }
- return TRUE;
- }
- /****************************************************************************
- * Name
- MonitorServerSocket
- * Type
- public
- * Function
- function to monitor a socket and accept a link
- * Return Value
- null
- * Parameters
- null
- *****************************************************************************/
- void CompletionPort::MonitorServerSocket()
- {
- DWORD dwWaitCode;
- WSANETWORKEVENTS wsaNetWorkEvents;
- while( true )
- {
- if( m_bQuitThread ) //判断监听线程退出条件是否满足
- {
- SetEvent(m_hQuitEvent);
- TRACE("Monitor Server Quit\n");
- return ;
- }
- dwWaitCode = WSAWaitForMultipleEvents(1, &m_wsaEvent, FALSE, 2000, FALSE);//等待网络事件
- if(dwWaitCode != WAIT_OBJECT_0)
- continue;
- if( SOCKET_ERROR == WSAEnumNetworkEvents(m_ListenSocket, m_wsaEvent,&wsaNetWorkEvents ))//枚举网络事件
- {
- int nErrorCode = WSAGetLastError();
- TRACE("WSAEnumNetworkEvents Error");
- }
- else
- {
- if( wsaNetWorkEvents.lNetworkEvents & FD_ACCEPT)
- {
- OnClientAccept();
- }
- }
- }
- }
- /****************************************************************************
- * Name
- OnClientAccept
- * Type
- public
- * Function
- function to monitor a socket and accept a link
- * Return Value
- null
- * Parameters
- null
- *****************************************************************************/
- void CompletionPort::OnClientAccept()
- {
- int nSockAddrLength = sizeof(SOCKADDR_IN);
- Client* pClntData = new Client();
- pClntData->m_hClientSock = accept(m_ListenSocket,
- (struct sockaddr*)&(pClntData->m_ClientAddress),
- &nSockAddrLength);
- if (INVALID_SOCKET == pClntData->m_hClientSock)
- {
- delete pClntData;
- }
- AddClient(pClntData);
- HANDLE hCompletePort = CreateIoCompletionPort((HANDLE)pClntData->m_hClientSock, m_hCOP,
- (DWORD)pClntData->m_hClientSock,0);
- if( hCompletePort != m_hCOP)
- {
- TRACE("Create Communication CompletionPort failure!\n");
- }
- ReadFile((HANDLE)pClntData->m_hClientSock, pClntData->m_pReceBuf, RECEIVE_SIZE, NULL,
- &pClntData->m_OverLapped);
- }
- /****************************************************************************
- * Name
- MonitorIoCompletionPort
- * Type
- public
- * Function
- function to monitor completionport
- * Return Value
- void
- * Parameters
- null
- *****************************************************************************/
- void CompletionPort::MonitorIoCompletionPort()
- {
- TRACE("Begin Monitor IoPort \n");
- BOOL bSuc = FALSE;
- DWORD dwNumBytes = 0;
- DWORD dwKey = -1;
- DWORD dwSockId = 0;
- LPOVERLAPPED completedOverlapped;
- int nLen =0;
- while( true )
- {
- //判断监听线程退出条件是否满足
- if( m_bIsQuit)
- {
- TRACE("Monitor IoCompletionPort Quit\n");
- SetEvent(m_hQuitEvent);
- return;
- }
- //查询完全端口状态
- dwKey = -1;
- bSuc = GetQueuedCompletionStatus( m_hCOP, &dwNumBytes, &dwKey, &completedOverlapped, 2000);
- if (bSuc==FALSE)
- {
- int nError = WSAGetLastError();
- if (nError == WSA_WAIT_TIMEOUT)
- {
- continue;
- }
- if (nError == ERROR_NETNAME_DELETED)
- {
- OnClientClose(dwKey);
- continue;
- }
- TRACE("GetQueuedCompletionStatus Error: %d\n", nError);
- continue;
- }
- if (dwKey>0)
- {
- dwSockId = dwKey;
- nLen = dwNumBytes;
- if( nLen > 0)
- {
- int index = -1;
- Client* pClient = GetClient(dwSockId, index);
- if( pClient == NULL)
- continue;
- try
- {
- //Sleep(50);
- if (nLen >1024)
- {
- nLen = 1024;
- //CDebug::ShowErroMessage("接收到数据长度过长!");
- }
- pClient->SetData(nLen);
- //ProcessData(pClient);
- //向完全端口发送读指令,等待下一次数据
- ZeroMemory(pClient->m_pReceBuf,RECEIVE_SIZE);
- ReadFile((HANDLE)pClient->m_hClientSock,pClient->m_pReceBuf,RECEIVE_SIZE,NULL,&pClient->m_OverLapped);
- }
- catch(...)
- {
- TRACE("catch an error");
- }
- }
- else
- {
- OnClientClose(dwSockId);
- }
- }
- }
- }
- /****************************************************************************
- * Name
- GetClient
- * Type
- public
- * Function
- get a pointer to point class of Client
- * Return Value
- Client*
- * Parameters
- DWORD dwSockId : socket ID
- int& index: the position in the vector
- *****************************************************************************/
- Client* CompletionPort::GetClient(DWORD dwSockId, int& index)
- {
- Client* pNewData = NULL;
- m_cs.lock();
- for (size_t i = 0; i < m_ClientVector.size(); i++)
- {
- if (m_ClientVector[i]->m_hClientSock == dwSockId)
- {
- index = i;
- pNewData = m_ClientVector[i];
- break;
- }
- }
- m_cs.unlock();
- return pNewData;
- }
- /****************************************************************************
- * Name
- OnClientClose
- * Type
- public
- * Function
- close the socket that dont translate data
- * Return Value
- BOOL
- * Parameters
- DWORD dwSockId: socket ID
- *****************************************************************************/
- BOOL CompletionPort::OnClientClose(DWORD dwSockId)
- {
- int index = -1;
- Client* pClient = GetClient(dwSockId, index);
- if ((NULL != pClient) && (-1 != index))
- {
- closesocket(pClient->m_hClientSock);
- DeleteClient(index);
- pClient = NULL;
- }
- return TRUE;
- }
- //----------------------------Client 管理-------------------------
- //************增加客户端*********************
- BOOL CompletionPort::AddClient(Client * const pClient)
- {
- if (!pClient)
- {
- return FALSE;
- }
- m_cs.lock();
- m_ClientVector.push_back(pClient);
- m_cs.unlock();
- return TRUE;
- }
- //************删除客户端*********************
- BOOL CompletionPort::DeleteClient(int index)
- {
- m_cs.lock();
- delete m_ClientVector[index];
- m_ClientVector.erase(m_ClientVector.begin() + index);
- m_cs.unlock();
- return TRUE;
- }
- //************查询客户端*********************
- Client * CompletionPort::GetClient(const char * ip)
- {
- Client* pNewClient = NULL;
- ULONG nAddr = inet_addr(ip);
- m_cs.lock();
- for (size_t i = 0; i < m_ClientVector.size(); i++)
- {
- if (m_ClientVector[i]->m_ClientAddress.sin_addr.s_addr == nAddr)
- {
- pNewClient = m_ClientVector[i];
- break;
- }
- }
- m_cs.unlock();
- return pNewClient;
- }
3,测试文件:
![](https://code.csdn.net/assets/CODE_ico.png)
- // IOCPTest.cpp : 定义控制台应用程序的入口点。
- //
- #include "stdafx.h"
- #include "IOCP_TCP.h"
- #include <iostream>
- int _tmain(int argc, _TCHAR* argv[])
- {
- CCriticalSection *p = new CCriticalSection;
- delete p;
- CompletionPort * cp = new CompletionPort();
- cp->Init("192.168.31.27", 4567); //需要修改为自己的ip
- cp->Active();
- char buff[1024]={0};
- char recBuff[1024]={0};
- int len;
- while (true)
- {
- scanf_s("%s", buff, 1023);
- len = strlen(buff);
- cp->SendData(buff, len, "192.168.31.27");<span style="white-space:pre"> </span>//客户端的ip
- ZeroMemory(recBuff,1024);
- cp->ReceiveData(recBuff, 1024, "192.168.31.27"); //客户端的ip
- printf("\n%s\n", recBuff);
- }
- delete cp;
- return 0;
- }
5,预编译头文件
![](https://code.csdn.net/assets/CODE_ico.png)
- // stdafx.h : include file for standard system include files,
- // or project specific include files that are used frequently, but
- // are changed infrequently
- //
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
- #define _WIN32_WINNT 0x0501
- #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
- #include <afxwin.h> // MFC core and standard components
- #include <afxext.h> // MFC extensions
- #ifndef _AFX_NO_OLE_SUPPORT
- #include <afxole.h> // MFC OLE classes
- #include <afxodlgs.h> // MFC OLE dialog classes
- #include <afxdisp.h> // MFC Automation classes
- #endif // _AFX_NO_OLE_SUPPORT
- #ifndef _AFX_NO_DB_SUPPORT
- #include <afxdb.h> // MFC ODBC database classes
- #endif // _AFX_NO_DB_SUPPORT
- #ifndef _AFX_NO_DAO_SUPPORT
- #include <afxdao.h> // MFC DAO database classes
- #endif // _AFX_NO_DAO_SUPPORT
- #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
- #ifndef _AFX_NO_AFXCMN_SUPPORT
- #include <afxcmn.h> // MFC support for Windows Common Controls
- #endif // _AFX_NO_AFXCMN_SUPPORT
- //外部库文件引用
- #include <afxmt.h>
- #include <afx.h>
- #include <afxtempl.h>
- #include <winsock2.h>
- #include <memory>
- //外部自定义头文件引用
- //#include "Resource.h"
- //#include "ICOMPro.h"
- //#include "datatype.h"
- //#include "Reg.h"
- //#include "Debug.h"
- //#include "Helper.h"
- #if defined(_WIN32_WCE_CEPC) || defined(_ARM_)
- #include "AtomCE.h"
- #endif
- //编译选项
- //[!if TRYCONNECT_TRUE]
- //#define _TRYCONNECT_TRUE
- //[!endif]
- //
- //[!if TRYCONNECT_USERDEFINE]
- //#define _TRYCONNECT_USEDEFINE
- //[!endif]
- //
- //[!if TRYCONNECT_USEPACKET]
- //#define _TRYCONNECT_USEPACKET
- //[!endif]
- //
- //[!if REOPENCOM]
- //#define _REOPENCOM
- //[!endif]
- //{{AFX_INSERT_LOCATION}}
- // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
- #include "lock.h"
此文章来自于【http://blog.csdn.net/huangxy10/article/details/16899481】
TCP完成端口服务器构建相关推荐
- Linux服务器上测试TCP/UDP端口的连通性
目录 说明 测试tcp端口的连通性: 使用nc命令来测试udp端口的连通性: 使用nc命令来测试tcp端口的连通性: 使用案例如下: 说明 翻译自: How to Test Port[TCP/UDP] ...
- 阿里云建站,重启阿里云服务器后网站打不开,该怎么办???如何检查TCP 80端口是否正常工作???
阿里云建站,重启阿里云服务器后网站打不开,该怎么办???如何检查TCP 80端口是否正常工作??? 本篇适用于阿里云云服务器ECS. 一.云服务器ECS为Ubuntu服务器 以下是在Ubuntu 16 ...
- 阿里云-默认封禁TCP 25端口出方向的访问流量,即您无法在阿里云上的云服务器通过TCP 25端口连接外部地址。
TCP 25端口解封申请 本页目录 背景信息 操作步骤 出于安全考虑,阿里云默认封禁TCP 25端口出方向的访问流量,即您无法在阿里云上的云服务器通过TCP 25端口连接外部地址. 背景信息 TCP ...
- linux系统怎么测试udp端口通不通,怎么在Linux服务器上测试TCP/UDP端口的连通性?...
翻译自: How to Test Port[TCP/UDP] Connectivity from a Linux Server (文档 ID 2212626.1) 适用于: Linux OS - Ve ...
- 优化Linux内核参数/etc/sysctl.conf sysctl 《高性能Linux服务器构建实战:运维监控、性能调优与集群应用》...
优化Linux内核参数/etc/sysctl.conf sysctl <高性能Linux服务器构建实战:运维监控.性能调优与集群应用> http://book.51cto.com/ar ...
- arm学习笔记005之Linux平台下TFTP服务器构建
TFTP(Trivial File Transfer Protocol,简单的文件传输协议)是 TCP/IP 协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂.开销不大的文件传 ...
- DNS服务器(DNS服务器构建,特殊的解析记录,多域名DNS服务器架构,DNF主从架构,DNS主从数据同步)
学前提示: 需要两台虚拟机 虚拟机A:主机名位svr7 IP:192.168.4.7 虚拟机B:主机名pc207 IP:192.168.207 一.进行环境的设置 1.修改两台虚拟机的SELinux ...
- 计算机网络套接字编程实验-TCP单进程循环服务器程序与单进程客户端程序(简单回声)
1.实验系列 ·Linux NAP-Linux网络应用编程系列 2.实验目的 ·理解并掌握在程序运行时从命令行读取数据的C语言编程方法: ·理解并掌握基于命令参数设置并获取IP与Port的C语言编程方 ...
- 计算机网络套接字编程实验-TCP多进程并发服务器程序与单进程客户端程序(简单回声)
1.实验系列 ·Linux NAP-Linux网络应用编程系列 2.实验目的 ·理解多进程(Multiprocess)相关基本概念,理解父子进程之间的关系与差异,熟练掌握基于fork()的多进程编程模 ...
- 高性能Linux服务器构建实战 服务器安全运维
文章目录 1. 安全运维 1.1 账户和登录安全 1.1.1 用户和用户组管理 1.1.2 系统服务管理 1.1.3 登录密码安全管理 1.1.4 用户root权限管理 1.1.5 系统欢迎页面管理 ...
最新文章
- DTrace memory leak 内存泄露
- CentOS6.5-源码编译安装最新MySQL5.7.10
- vuex实践之路——笔记本应用(三)
- 虚幻gameframe_【虚幻4】从0开始的Galgame开发框架(2)--MainManager
- 文本处理三剑客之sed
- SpringBoot异常处理-自定义HandlerExceptionResolver
- 走访近20家代工厂后:近千块的大牌T恤,成本只要几十块
- agaular 离线文档_Zeal 国外一款面向开发者的离线文档查看工具
- DIV的摇晃效果---jquery实现
- 2.《Spring学习笔记-MVC》系列文章,讲解返回json数据的文章共有3篇,分别为:...
- jq方法中 $(window).load() 与 $(document).ready() 的区别
- Java调用so文件
- cat6 万兆_专业扫盲Cat5e/Cat6/Cat6a/Cat7网线系列
- Flink1.12 文档
- 获取视频旋转角度,并对视频进行旋转
- 2022年2月语音合成(TTS)和语音识别(ASR)论文月报
- 【杂七杂八】Dreamweaver在Surface高分辨率下工具栏字体和按钮太小的解决办法
- Python解炸金花问题
- 利用SUS实现自动补丁管理
- vue-chartjs画渐变色