First Commit
This commit is contained in:
commit
8b13aa7d7a
268
SimpleSock.cpp
Normal file
268
SimpleSock.cpp
Normal file
|
@ -0,0 +1,268 @@
|
|||
#include "SimpleSock.h"
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
namespace SimpleSock {
|
||||
|
||||
void FetchLastError(int& code, std::string& msg)
|
||||
{
|
||||
code = GetLastError();
|
||||
LPSTR buffer = nullptr;
|
||||
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, 0, (LPSTR)&buffer, 0, NULL);
|
||||
msg = std::string(buffer, size);
|
||||
LocalFree(buffer);
|
||||
}
|
||||
|
||||
sock::sock()
|
||||
{
|
||||
fd = -1;
|
||||
_code = 0;
|
||||
}
|
||||
|
||||
sock::sock(sock&& s) noexcept
|
||||
{
|
||||
fd = s.fd;
|
||||
s.fd = -1;
|
||||
_code = 0;
|
||||
}
|
||||
|
||||
sock::~sock()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
int sock::create_socket()
|
||||
{
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
FetchLastError(_code, _msg);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sock::connect(const std::string& ip, int port)
|
||||
{
|
||||
if (fd > 0)
|
||||
{
|
||||
_code = -1;
|
||||
_msg = "[SimpleSock] Socket already connected.";
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (create_socket() < 0) return -1;
|
||||
|
||||
struct sockaddr_in saddr;
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
if (inet_pton(AF_INET, ip.c_str(), &(saddr.sin_addr.s_addr)) != 1)
|
||||
{
|
||||
FetchLastError(_code, _msg);
|
||||
return -1;
|
||||
}
|
||||
saddr.sin_port = htons(port);
|
||||
saddr.sin_family = AF_INET;
|
||||
|
||||
int ret = ::connect(fd, (sockaddr*)&saddr, sizeof(saddr));
|
||||
if (ret < 0)
|
||||
{
|
||||
FetchLastError(_code, _msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sock::bind(const std::string& ip, int port)
|
||||
{
|
||||
if (fd > 0)
|
||||
{
|
||||
_code = -1;
|
||||
_msg = "[SimpleSock] Socket already binded.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_in saddr;
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
|
||||
if (inet_pton(AF_INET, ip.c_str(), &(saddr.sin_addr.s_addr)) != 1)
|
||||
{
|
||||
FetchLastError(_code, _msg);
|
||||
return -1;
|
||||
}
|
||||
saddr.sin_port = htons(port);
|
||||
saddr.sin_family = AF_INET;
|
||||
|
||||
int ret = ::bind(fd, (sockaddr*)&saddr, sizeof(saddr));
|
||||
if (ret < 0)
|
||||
{
|
||||
FetchLastError(_code, _msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sock::listen(int backlog)
|
||||
{
|
||||
int ret = ::listen(fd, backlog);
|
||||
if (ret < 0)
|
||||
{
|
||||
FetchLastError(_code, _msg);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sock sock::accept()
|
||||
{
|
||||
sockaddr_in saddr;
|
||||
socklen_t saddrsz = sizeof(saddr);
|
||||
int ret = ::accept(fd, (sockaddr*)&saddr, &saddrsz);
|
||||
if (ret < 0)
|
||||
{
|
||||
FetchLastError(_code, _msg);
|
||||
return sock();
|
||||
}
|
||||
else
|
||||
{
|
||||
sock s;
|
||||
s.fd = ret;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
int sock::send(const void* buffer, size_t length)
|
||||
{
|
||||
int ret = ::send(fd, (char*)buffer, length, 0);
|
||||
if (ret <= 0)
|
||||
{
|
||||
FetchLastError(_code, _msg);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sock::sendall(const void* buffer, size_t length)
|
||||
{
|
||||
size_t done = 0;
|
||||
while (done < length)
|
||||
{
|
||||
int ret = send((char*)buffer + done, length - done);
|
||||
if (ret <= 0) return ret;
|
||||
done += ret;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
int sock::recv(void* buffer, size_t length)
|
||||
{
|
||||
int ret = ::recv(fd, (char*)buffer, length, 0);
|
||||
if (ret <= 0)
|
||||
{
|
||||
FetchLastError(_code, _msg);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sock::close()
|
||||
{
|
||||
if (fd > 0)
|
||||
{
|
||||
closesocket(fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool sock::valid()
|
||||
{
|
||||
return fd >= 0;
|
||||
}
|
||||
|
||||
int sock::getError()
|
||||
{
|
||||
return _code;
|
||||
}
|
||||
|
||||
std::string sock::getErrorMessage()
|
||||
{
|
||||
return _msg;
|
||||
}
|
||||
|
||||
std::tuple<std::vector<std::string>, int, std::string> DNSResolve(const std::string& host)
|
||||
{
|
||||
std::vector<std::string> vec;
|
||||
int _code;
|
||||
std::string _msg;
|
||||
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
struct addrinfo* result = nullptr;
|
||||
|
||||
int ret = getaddrinfo(host.c_str(), NULL, &hints, &result);
|
||||
if (ret)
|
||||
{
|
||||
FetchLastError(_code, _msg);
|
||||
return std::make_tuple(vec, _code, _msg);
|
||||
}
|
||||
|
||||
for (struct addrinfo* ptr = result; ptr; ptr = ptr->ai_next)
|
||||
{
|
||||
if (ptr->ai_family == AF_INET)
|
||||
{
|
||||
struct sockaddr_in* paddr = (struct sockaddr_in*)(ptr->ai_addr);
|
||||
char ip_buff[128] = { 0 };
|
||||
const char* ptr = inet_ntop(AF_INET, &(paddr->sin_addr), ip_buff, 128);
|
||||
if (ptr)
|
||||
{
|
||||
vec.push_back(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
FetchLastError(_code, _msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
freeaddrinfo(result);
|
||||
|
||||
return std::make_tuple(vec, _code, _msg);
|
||||
}
|
||||
|
||||
int ConnectWithHttpProxy(sock& s, const std::string& proxyIP, int proxyPort, const std::string& host, int port)
|
||||
{
|
||||
int ret = s.connect(proxyIP, proxyPort);
|
||||
if (ret < 0) return -1;
|
||||
char request[1024] = { 0 };
|
||||
snprintf(request, sizeof(request), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n\r\n", host.c_str(), port, host.c_str(), port);
|
||||
ret = s.sendall(request, strlen(request));
|
||||
if (ret != strlen(request)) return -2;
|
||||
char buffer[8] = { 0 };
|
||||
std::string result;
|
||||
while (1)
|
||||
{
|
||||
ret = s.recv(buffer, 1);
|
||||
if (ret <= 0) return ret;
|
||||
result.push_back(buffer[0]);
|
||||
if (result.find("\r\n\r\n") != std::string::npos)
|
||||
{
|
||||
printf("%s\n===== HTTP PROXY CONNECT FINISHED =====\n", result.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int InitSimpleSock()
|
||||
{
|
||||
WORD wd;
|
||||
WSAData wdt;
|
||||
wd = MAKEWORD(2, 2);
|
||||
return WSAStartup(wd, &wdt);
|
||||
}
|
||||
}
|
40
SimpleSock.h
Normal file
40
SimpleSock.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace SimpleSock
|
||||
{
|
||||
class sock
|
||||
{
|
||||
public:
|
||||
sock();
|
||||
sock(sock&&) noexcept;
|
||||
~sock();
|
||||
sock(const sock&) = delete;
|
||||
sock& operator = (const sock&) = delete;
|
||||
int connect(const std::string& ip, int port);
|
||||
int bind(const std::string& ip, int port);
|
||||
int listen(int backlog = 0);
|
||||
sock accept();
|
||||
int send(const void* buffer, size_t length);
|
||||
int sendall(const void* buffer, size_t length);
|
||||
int recv(void* buffer, size_t length);
|
||||
void close();
|
||||
|
||||
bool valid();
|
||||
int getError();
|
||||
std::string getErrorMessage();
|
||||
private:
|
||||
int create_socket();
|
||||
|
||||
int fd;
|
||||
int _code;
|
||||
std::string _msg;
|
||||
};
|
||||
|
||||
std::tuple<std::vector<std::string>, int, std::string> DNSResolve(const std::string& host);
|
||||
int ConnectWithHttpProxy(sock& s, const std::string& proxyIP, int proxyPort, const std::string& host, int port);
|
||||
|
||||
int InitSimpleSock();
|
||||
}
|
35
test.cpp
Normal file
35
test.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#include "SimpleSock.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
using namespace SimpleSock;
|
||||
|
||||
int main()
|
||||
{
|
||||
InitSimpleSock();
|
||||
|
||||
sock s;
|
||||
if (ConnectWithHttpProxy(s, "127.0.0.1", 12759, "106.53.10.163", 80) < 0)
|
||||
{
|
||||
cout << "Failed Connect Http Proxy" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* data = "GET / HTTP/1.1\r\nConnection: close\r\nHost: paste.kiritow.com\r\n\r\n";
|
||||
if (s.sendall(data, strlen(data)) != strlen(data))
|
||||
{
|
||||
cout << "send failed" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char buff[1024] = { 0 };
|
||||
int ret;
|
||||
while ((ret = s.recv(buff, 1024)) > 0)
|
||||
{
|
||||
string temp = string(buff, ret);
|
||||
cout << temp << endl;
|
||||
memset(buff, 0, 1024);
|
||||
}
|
||||
cout << "\nFinalCode: " << ret << " Errcode:" << s.getError() << " ErrMsg:" << s.getErrorMessage() << endl;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user