非阻塞Socket

工程-》属性》链接器》输入》附加依赖项》ws2_32.lib

HTTPSocket.h

#pragma once
#include 

using std::string;

typedef unsigned short USHORT;

const USHORT HTTP_TIMEOUT = 5000;
const USHORT MAX_EXTERN_LEN = 200;
const USHORT MAX_BUF_LEN = 4000;

class CHTTPSocket
{
private:
	USHORT m_usPort;
	long m_lTimeOut;
	string m_strIP;
//public:
//	char *m_lpSendBuf;
//	char *m_lpRecvBuf;

public:
	CHTTPSocket(void);
	~CHTTPSocket(void);
private:
	virtual bool Init();
	virtual void Exit();

public:
	//参数配置
	long GetTimeOut();
	void SetTimeOut(long lTimeOut);

	USHORT GetPort();
	void SetPorts(USHORT usPort);

	string GetIP();
	void SetIP(string strIP);

	//非阻塞方式发送数据
	bool SocketSend(const char* cMsgSend, const int nMsgSendLen, char* cMsgRecv, int *nRecvMsgLen);
};


 

HTTPSocket.cpp

#include "HTTPSocket.h"
#include 

CHTTPSocket::CHTTPSocket(void):	m_usPort(0)
							, m_lTimeOut(HTTP_TIMEOUT)
							, m_strIP("127.0.0.1")
{
	Init();
}

CHTTPSocket::~CHTTPSocket(void)
{
	Exit();
}

bool CHTTPSocket::Init()
{
	int ret;
	WORD wVersion = MAKEWORD(2, 2);
	WSADATA wsaData;
	ret = WSAStartup(wVersion, &wsaData);
	
	return ret == 0;
}

void CHTTPSocket::Exit()
{
	WSACleanup();
}

long CHTTPSocket::GetTimeOut()
{
	return m_lTimeOut;
}
void CHTTPSocket::SetTimeOut(long lTimeOut)
{
	m_lTimeOut	= lTimeOut;
}

USHORT CHTTPSocket::GetPort()
{
	return m_usPort;
}
void CHTTPSocket::SetPorts(USHORT usPort)
{
	m_usPort = usPort;
}

string CHTTPSocket::GetIP()
{
	return m_strIP;
}
void CHTTPSocket::SetIP(string strIP)
{
	m_strIP = strIP;
}

//======================================================================================================
// 函 数 名:SocketSend
// 功能描述:自己封装的HTTP请求方法,可以根据需要衍生出DoPut、DoPost、DoGet、DoDelete
// 输入参数:cMsgSend:要发送的消息
//           nMsgSendLen:要发送的消息长度
// 输出参数:cMsgRecv:需要向对端发送的消息
// 输入/输出参数:nRecvMsgLen: cMsgRecv的长度/实际接收到的长度
// 返回参数:1:成功
//           0:失败
// 创建日期:
// 修改日期:
// 作    者:
// 附加说明:由于CSocket和CHTTPConnect类不能很好的支持超时的设置,因此这里使用windows socket方法来实现通信
//========================================================================================================
 bool CHTTPSocket::SocketSend(const char* cMsgSend, const int nMsgSendLen, char* cMsgRecv, int *nRecvMsgLen)
 {
 	if (NULL == cMsgSend || NULL == cMsgRecv)
 	{
 		return FALSE;
 	}
 
 	BOOL bConnected = TRUE;
 
 	SOCKADDR_IN Rtaddr;  
 	Rtaddr.sin_family = AF_INET;  
 	Rtaddr.sin_addr.S_un.S_addr = inet_addr(m_strIP.c_str());  
 	Rtaddr.sin_port = htons(m_usPort);  
 
 	//创建套接字
 	SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
 	if (s == INVALID_SOCKET)  
 	{  
 		DWORD QQ = WSAGetLastError();
 		return FALSE;
 	}
 
 	//设置为非阻塞模式
 	DWORD dwset = 1;  
 	int nRet = ioctlsocket(s, FIONBIO, (LPDWORD)&dwset); 
 	if (nRet == SOCKET_ERROR)
 	{
 		closesocket(s);  
 		return FALSE;
 	}
 
 	//连接
 	if (SOCKET_ERROR == connect(s, (SOCKADDR*)&Rtaddr, sizeof(Rtaddr)))
 	{
 		fd_set set;  
 		FD_ZERO(&set);  
 		FD_SET(s, &set);  
 
 		timeval timeout;  
 
 		timeout.tv_sec = 0;  
 		//这个单位是微秒
 		timeout.tv_usec = m_lTimeOut * 1000;  
 
 		nRet = select(NULL, NULL, &set, NULL, &timeout);
 
 		if (SOCKET_ERROR == nRet)
 		{  
 			closesocket(s);  
 			return FALSE;
 		}    
 	}
 
 	//继续设置为阻塞模式
 	dwset = 0;
 	nRet = ioctlsocket(s, FIONBIO, (LPDWORD)&dwset);  
 	if (nRet == SOCKET_ERROR)  
 	{  
 		closesocket(s);  
 		return  FALSE;
 	}  
 
 	//设置发送的超时时长
 	nRet = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*)&m_lTimeOut, sizeof(m_lTimeOut));
 	if (nRet == SOCKET_ERROR)
 	{
 		closesocket(s);  
 		return  FALSE;
 	}
 
 	//设置接收的超时时长
 	nRet = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&m_lTimeOut, sizeof(m_lTimeOut));
 	if (nRet == SOCKET_ERROR)
 	{
 		closesocket(s);  
 		return  FALSE;
 	}
 
 	//发送
 	nRet = send(s, cMsgSend, nMsgSendLen, 0);
 	if(SOCKET_ERROR == nRet)
 	{
 		closesocket(s);  
 		return  FALSE;
 	}
 
 	//接收
 	nRet = recv(s, cMsgRecv, *nRecvMsgLen, 0);
 	if (nRet < 0)
 	{
 		closesocket(s);  
 		return  FALSE;
 	}
 
 	closesocket(s);  
 
 	return TRUE;
 }


 

使用:

#include 
#include 
#include "HTTPSocket.h"

void main()
{
	/*
	PUT  /agentgateway/resource/onlineagent/108 HTTP/1.1
	HOST: 10.166.45.21:8000
	Content-Type: application/json; charset=UTF-8
	Content-Length: 123

	{
		"password":"",
			"phonenum":"7100",
			"autoanswer":"true",
			"autoenteridle":"true",
			"releasephone":"true",
			"status":4
	}
	*/

	char sendBuf[MAX_BUF_LEN], recvBuf[MAX_BUF_LEN];
	memset(recvBuf, 0, MAX_BUF_LEN);
	int len = MAX_BUF_LEN;

	CHTTPSocket http;
	http.SetIP("10.166.45.21");
	http.SetPorts(8000);

	sprintf_s(sendBuf, "%s", "PUT  /agentgateway/resource/onlineagent/108 HTTP/1.1\r\n"\
								"Content-Type: application/json; charset=UTF-8\r\n"\
								"Host: 10.166.45.21:8000\r\n"\
								"Content-Length: 123\r\n\r\n"\
								"{\r\n"\
								"\"password\":\"\",\r\n"\
								"\"phonenum\":\"7100\",\r\n"\
								"\"autoanswer\":\"true\",\r\n"\
								"\"autoenteridle\":\"true\",\r\n"\
								"\"releasephone\":\"true\",\r\n"\
								"\"status\":4\r\n"\
								"}"
								);

	// http://10.166.45.21:8000/agentgateway/resource//thirdparty/ykf61758/authtype
	http.SocketSend(sendBuf, len, recvBuf, &len);
}


 

你可能感兴趣的:(C/C++)