头文件:
#ifndef __MANAGE_NET__
#define __MANAGE_NET__
#include <vector>
#include <string>
#include <process.h>
#include <winsock2.h>
#include <functional>
using namespace std;
class ManageNet
{
public:
ManageNet();
~ManageNet();
public:
static ManageNet* m_Instance;
static ManageNet* GetInstance()
{
if (!m_Instance) {
m_Instance = new ManageNet;
}
return m_Instance;
}
static void ReleaseInstance()
{
if (m_Instance) {
delete m_Instance;
m_Instance = NULL;
}
}
bool SetFunc(const std::function<void(const char*, long)>&pFunc);
bool Init(const char* pstrIP, long nPort);
bool Write(unsigned char* pData, long nSize);
void Uninit();
private:
bool Connect(const char* pstrIP, long nPort);
void DisConnect();
long Read(unsigned char* pData, long nSize);
static unsigned int __stdcall Process(void* args);
private:
std::function<void(const char*, long)> m_pFunc;
private:
HANDLE m_threadRecv;
HANDLE m_threadEvent;
private:
string m_strIP;
long m_nPort;
private:
SOCKET sClient;
};
#endif
源文件:
#include "TcpClient.h"
#pragma warning(disable:4996)
#pragma comment(lib, "ws2_32.lib")
ManageNet* ManageNet::m_Instance = NULL;
ManageNet::ManageNet()
{
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata);
m_threadRecv = INVALID_HANDLE_VALUE;
m_threadEvent = INVALID_HANDLE_VALUE;
}
ManageNet::~ManageNet()
{
Uninit();
WSACleanup();
}
bool ManageNet::SetFunc(const std::function<void(const char*, long)>& pFunc)
{
if (pFunc) {
m_pFunc = pFunc;
return true;
}
return false;
}
bool ManageNet::Connect(const char* pstrIP, long nPort)
{
sClient = socket(AF_INET, SOCK_STREAM, 0);
if (sClient == INVALID_SOCKET) {
return false;
}
struct sockaddr_in seraddr;
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(nPort);
seraddr.sin_addr.S_un.S_addr = inet_addr(pstrIP);//IP地址
if (connect(sClient, (const struct sockaddr*)&seraddr, sizeof(seraddr)) == SOCKET_ERROR) {
DWORD dwErr = GetLastError();
return false;
}
int nTimeout = 1000;//
setsockopt(sClient, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeout, sizeof(int));
setsockopt(sClient, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeout, sizeof(int));
return true;
}
bool ManageNet::Init(const char* pstrIP, long nPort)
{
if (!pstrIP) {
return false;
}
bool bRet = Connect(pstrIP, nPort);
if (bRet) {
m_strIP = pstrIP;
m_nPort = nPort;
m_threadEvent = CreateEvent(NULL, true, false, L"");
m_threadRecv = (HANDLE)_beginthreadex(NULL, 0, Process, this, 0, NULL);
return true;
}
return false;
}
long ManageNet::Read(unsigned char* pData, long nSize)
{
if (sClient != INVALID_SOCKET) {
return recv(sClient, (char*)pData, nSize, 0);
}
return 0;
}
bool ManageNet::Write(unsigned char* pData, long nSize)
{
long nLen = send(sClient, (char*)pData, nSize, 0);
if (nLen == SOCKET_ERROR) {
return false;
}
return true;
}
void ManageNet::Uninit()
{
if (m_threadRecv != INVALID_HANDLE_VALUE && m_threadEvent != INVALID_HANDLE_VALUE) {
SetEvent(m_threadEvent);
WaitForSingleObject(m_threadRecv, INFINITE);
CloseHandle(m_threadRecv);
CloseHandle(m_threadEvent);
m_threadRecv = INVALID_HANDLE_VALUE;
m_threadEvent = INVALID_HANDLE_VALUE;
}
DisConnect();
}
void ManageNet::DisConnect()
{
closesocket(sClient);
sClient = INVALID_SOCKET;
}
unsigned int ManageNet::Process(void* args)
{
ManageNet* pThis = (ManageNet*)args;
while (true) {
if (WaitForSingleObject(pThis->m_threadEvent, 10) == WAIT_OBJECT_0) {
break;
}
char cData[2048] = { 0 };
long nRet = pThis->Read((unsigned char*)cData, 2048);
if (nRet > 0) {
if (pThis->m_pFunc) {
pThis->m_pFunc(cData, nRet);
}
}
else {
if (nRet == 0) {//不能在这里调用Uninit。因为会发生死锁
pThis->DisConnect();
pThis->Connect(pThis->m_strIP.c_str(), pThis->m_nPort);
}
else if (nRet == SOCKET_ERROR) {
if (WSAGetLastError() != WSAETIMEDOUT) {
pThis->DisConnect();
pThis->Connect(pThis->m_strIP.c_str(), pThis->m_nPort);
}
}
}
}
return 0;
}
调用:
ManageNet::GetInstance()->SetFunc(TcpDataOutputCB);
ManageNet::GetInstance()->Init("127.0.0.1", 8000);