编码转换
//UNICODE 转为 ASCII
string WCHAR_TO_ACSII(wstring& strWide)
{
int asciisize = ::WideCharToMultiByte(CP_OEMCP, 0, strWide.c_str(), -1, NULL, 0, NULL, NULL);
if (asciisize == ERROR_NO_UNICODE_TRANSLATION)
{
throw std::exception("Invalid UTF-8 sequence.");
}
if (asciisize == 0)
{
throw std::exception("Error in conversion.");
}
std::vector<char> resultstring(asciisize);
int convresult = ::WideCharToMultiByte(CP_OEMCP, 0, strWide.c_str(), -1, &resultstring[0], asciisize, NULL, NULL);
if (convresult != asciisize)
{
throw std::exception("La falla!");
}
return std::string(&resultstring[0]);
}
//ASCII 转 UNICODE
wstring ACSII_TO_WCHAR(string& strAscii)
{
int widesize = MultiByteToWideChar(CP_ACP, 0, (char*)strAscii.c_str(), -1, NULL, 0);
if (widesize == ERROR_NO_UNICODE_TRANSLATION) {
throw std::exception("Invalid UTF-8 sequence.");
}
if (widesize == 0)
{
throw std::exception("Error in conversion.");
}
std::vector<wchar_t> resultstring(widesize);
int convresult = MultiByteToWideChar(CP_ACP, 0, (char*)strAscii.c_str(), -1, &resultstring[0], widesize);
if (convresult != widesize)
{
throw std::exception("La falla!");
}
return std::wstring(&resultstring[0]);
}
//UNICODE 转 UTF8
std::string UNICODE_TO_UTF8(const std::wstring& strUnicode)
{
int utf8size = ::WideCharToMultiByte(CP_UTF8, 0, strUnicode.c_str(), -1, NULL, 0, NULL, NULL);
if (utf8size == 0)
{
throw std::exception("Error in conversion.");
}
std::vector<char> resultstring(utf8size);
int convresult = ::WideCharToMultiByte(CP_UTF8, 0, strUnicode.c_str(), -1, &resultstring[0], utf8size, NULL, NULL);
if (convresult != utf8size)
{
throw std::exception("La falla!");
}
return std::string(&resultstring[0]);
}
//UTF-8 转 UNICODE
std::wstring UTF8_TO_UNICODE(const std::string& strUtf8)
{
int widesize = ::MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, NULL, 0);
if (widesize == ERROR_NO_UNICODE_TRANSLATION) {
throw std::exception("Invalid UTF-8 sequence.");
}
if (widesize == 0)
{
throw std::exception("Error in conversion.");
}
std::vector<wchar_t> resultstring(widesize);
int convresult = ::MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, &resultstring[0], widesize);
if (convresult != widesize)
{
throw std::exception("La falla!");
}
return std::wstring(&resultstring[0]);
}
//ASCII 转 UTF8
string ASCII_TO_UTF8(string& strAscii)
{
string strRet("");
wstring wstr = ACSII_TO_WCHAR(strAscii);
strRet = UNICODE_TO_UTF8(wstr);
return strRet;
}
//UTF-8 转 ASCII
string UTF8_TO_ASCII(string& strUtf8)
{
string strRet("");
wstring wstr = UTF8_TO_UNICODE(strUtf8);
strRet = WCHAR_TO_ACSII(wstr);
return strRet;
}
HttpClient头文件
#pragma once
#include
#include
#include
#include
#include
#include
#pragma comment(lib, "ws2_32.lib")
const int BUFFER_SIZE = 4096;
class HttpClient
{
public:
HttpClient();
~HttpClient();
void SetHost(const std::string& host);
void SetPort(const int& port);
void SetPath(const std::string& path);
std::string GetHost() const;
int GetPort() const;
std::string GetPath() const;
void SetUrl(const std::string& host, const int& port, const std::string& path);
void SetUrl(const std::string& url);
std::string SetRequestParameter(const std::string& content, const std::string& contentType = "text/xml;charset=utf-8");
std::string PostRequest(const std::string& request);
static std::string PostRequestThread(const std::string& host, const int& port, const std::string& request);
private:
std::string m_sHost;
int m_nPort;
std::string m_sPath;
};
HttpClient源文件
#include "HttpClient.h"
#include
#define USE_FIONBIO_MODE
HttpClient::HttpClient()
{
m_sHost = "";
m_nPort = 0;
m_sPath = "";
}
HttpClient::~HttpClient()
{
}
void HttpClient::SetHost(const std::string& host)
{
m_sHost = host;
}
void HttpClient::SetPort(const int& port)
{
m_nPort = port;
}
void HttpClient::SetPath(const std::string& path)
{
m_sPath = path;
}
std::string HttpClient::GetHost() const
{
return std::string(m_sHost);
}
int HttpClient::GetPort() const
{
return m_nPort;
}
std::string HttpClient::GetPath() const
{
return std::string(m_sPath);
}
void HttpClient::SetUrl(const std::string& host, const int& port, const std::string& path)
{
m_sHost = host;
m_nPort = port;
m_sPath = path;
}
void HttpClient::SetUrl(const std::string& url)
{
std::string sUrl = url;
// 查找 "http://" 或 "https://"
size_t protocolPos = sUrl.find("://");
if (protocolPos == std::string::npos)
{
return;
}
// 提取协议部分并截取 URL
std::string protocol = sUrl.substr(0, protocolPos);
std::string remainingUrl = sUrl.substr(protocolPos + 3); // 跳过协议名称和 "://"
// 查找 IP 和端口
size_t ipPos = remainingUrl.find("/");
if (ipPos == std::string::npos)
{
return;
}
std::string ipAndPort = remainingUrl.substr(0, ipPos);
// 分离 IP 和端口
size_t portPos = ipAndPort.find(":");
if (portPos != std::string::npos)
{
m_sHost = ipAndPort.substr(0, portPos);
m_nPort = std::atoi(ipAndPort.substr(portPos + 1).c_str());
}
else
{
m_sHost = ipAndPort;
m_nPort = 0;
}
// 提取路径部分
m_sPath = remainingUrl.substr(ipPos);
std::cout << "======================================================" << std::endl;
std::cout << "IP: " << m_sHost << std::endl;
std::cout << "Port: " << m_nPort << std::endl;
std::cout << "Path: " << m_sPath << std::endl;
std::cout << "======================================================" << std::endl;
}
std::string HttpClient::SetRequestParameter(const std::string& content, const std::string& contentType)
{
std::string sHeader =
"POST " + m_sPath + " HTTP/1.1\r\n" +
"Host: " + m_sHost + "\r\n" +
"Content-Type: " + contentType + "\r\n" +
"Content-Length: " + std::to_string(content.length()) + "\r\n" +
"Connection: close\r\n" +
"\r\n" + content;
return std::string(sHeader);
}
std::string HttpClient::PostRequest(const std::string& request)
{
// 初始化Winsock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
std::cerr << "Failed to initialize Winsock." << std::endl;
return "";
}
// 创建套接字
SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == INVALID_SOCKET)
{
std::cerr << "Failed to create socket." << std::endl;
WSACleanup();
return "";
}
// 设置服务器地址
sockaddr_in serverAddress{};
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(m_nPort);
if (inet_pton(AF_INET, m_sHost.c_str(), &(serverAddress.sin_addr)) <= 0)
{
std::cerr << "Invalid address/Address not supported." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
int timeout = 2000;//ms
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR ||
setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR)
{
std::cerr << "setsockopt failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
#ifdef USE_FIONBIO_MODE
//设置connect非阻塞方式连接
unsigned long ul = 1;
if (ioctlsocket(sockfd, FIONBIO, (unsigned long*)&ul) == SOCKET_ERROR)
{
std::cerr << "ioctlsocket failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
// 连接服务器(设为非阻塞等待)
connect(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
#else
if (connect(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == SOCKET_ERROR)
{
std::cerr << "connect failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
#endif
#ifdef USE_FIONBIO_MODE
//select 模型,设置connect超时
struct timeval tagTimeout;
fd_set _set;
FD_ZERO(&_set);
FD_SET(sockfd, &_set);
int time = (timeout < 1000) ? 1 : timeout / 1000;
tagTimeout.tv_sec = time; //连接超时时间(s)
tagTimeout.tv_usec = 0;
if (select(0, 0, &_set, 0, &tagTimeout) <= 0)
{
std::cerr << "Connection failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
// 设回阻塞模式
unsigned long ul1 = 0;
if (ioctlsocket(sockfd, FIONBIO, (unsigned long*)&ul1) == SOCKET_ERROR)
{
std::cerr << "Connection failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
#endif
// 发送请求
if (send(sockfd, request.c_str(), request.length(), 0) == SOCKET_ERROR)
{
std::cerr << "Send request failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
// 接收响应
char buffer[BUFFER_SIZE];
std::string response;
int nBytesRead;
while ((nBytesRead = recv(sockfd, buffer, BUFFER_SIZE - 1, 0)) > 0)
{
response.append(buffer, nBytesRead);
memset(buffer, 0, sizeof(buffer));
}
// 关闭套接字
closesocket(sockfd);
WSACleanup();
return UTF8_TO_ASCII(response);
}
std::string HttpClient::PostRequestThread(const std::string& host, const int& port, const std::string& request)
{
// 初始化Winsock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
std::cerr << "Failed to initialize Winsock." << std::endl;
return "";
}
// 创建套接字
SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == INVALID_SOCKET)
{
std::cerr << "Failed to create socket." << std::endl;
WSACleanup();
return "";
}
// 设置服务器地址
sockaddr_in serverAddress{};
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(port);
if (inet_pton(AF_INET, host.c_str(), &(serverAddress.sin_addr)) <= 0)
{
std::cerr << "Invalid address/Address not supported." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
int timeout = 1000;//ms
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR ||
setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR)
{
std::cerr << "setsockopt failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
#ifdef USE_FIONBIO_MODE
//设置connect非阻塞方式连接
unsigned long ul = 1;
if (ioctlsocket(sockfd, FIONBIO, (unsigned long*)&ul) == SOCKET_ERROR)
{
std::cerr << "ioctlsocket failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
// 连接服务器(设为非阻塞等待)
connect(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
#else
if (connect(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == SOCKET_ERROR)
{
std::cerr << "connect failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
#endif
#ifdef USE_FIONBIO_MODE
//select 模型,设置connect超时
struct timeval tagTimeout;
fd_set _set;
FD_ZERO(&_set);
FD_SET(sockfd, &_set);
int time = (timeout < 1000) ? 1 : timeout / 1000;
tagTimeout.tv_sec = time; //连接超时时间(s)
tagTimeout.tv_usec = 0;
if (select(0, 0, &_set, 0, &tagTimeout) <= 0)
{
std::cerr << "Connection failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
// 设回阻塞模式
unsigned long ul1 = 0;
if (ioctlsocket(sockfd, FIONBIO, (unsigned long*)&ul1) == SOCKET_ERROR)
{
std::cerr << "Connection failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
#endif
// 发送请求
if (send(sockfd, request.c_str(), request.length(), 0) == SOCKET_ERROR)
{
std::cerr << "Send request failed." << std::endl;
closesocket(sockfd);
WSACleanup();
return "";
}
// 接收响应
char buffer[BUFFER_SIZE];
std::string response;
int nBytesRead;
while ((nBytesRead = recv(sockfd, buffer, BUFFER_SIZE - 1, 0)) > 0)
{
response.append(buffer, nBytesRead);
memset(buffer, 0, sizeof(buffer));
}
// 关闭套接字
closesocket(sockfd);
WSACleanup();
return UTF8_TO_ASCII(response);
}
测试
int main()
{
std::string xmlString = "这是xml数据";
std::string slUrl = "http://192.168.1.115:1234/services/MyService?wsdl";
HttpClient httpClient;
//httpClient.SetUrl("192.168.1.115", 1234, "/services/MyService?wsdl");
httpClient.SetUrl(slUrl);
std::string request = httpClient.SetRequestParameter(xmlString);
std::string response = httpClient.PostRequest(request);
//std::string response = httpClient.PostRequestThread("10.30.35.116", 9005, request);
//解析数据
// ....
//打印
std::cout << "\nResponse:\n" << response << std::endl;
getchar();
return 0;
}