#if defined _WIN32 || defined _WIN64
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#endif
#include <stdio.h>
#include <string.h>
#define min(a, b) (((a)<(b))?(a):(b))
#define max(a, b) (((a)>(b))?(a):(b))
#ifndef __cplusplus
typedef enum {false, true} bool;
#endif
typedef struct
{
int sock;
const char* address;
unsigned short port;
} sock_info;
const char* GetHostLocation(char* Buffer, sock_info* info)
{
const char* addr
= strstr(info
->address
, "://");
if (addr)
if ((addr
= strstr(Buffer
, "/"))) Buffer[addr - Buffer] = '\0';
return addr ? Buffer : NULL;
}
const char* GetRequestLocation(char* Buffer, sock_info* info)
{
const char* addr
= strstr(info
->address
, "://");
if (Buffer)
{
if (addr)
if ((addr
= strstr(Buffer
, "/"))) {
}
}
else
{
return addr ? addr + 1 : NULL;
}
return addr ? Buffer : NULL;
}
bool init()
{
#if defined _WIN32 || defined _WIN64
WSADATA wsaData = {0};
return !WSAStartup(MAKEWORD(2, 2), &wsaData);
#else
return true;
#endif
}
void destroy(sock_info* info)
{
#if defined _WIN32 || defined _WIN64
shutdown(info->sock, SD_BOTH);
closesocket(info->sock);
WSACleanup();
#else
shutdown(info->sock, SHUT_RDWR);
close(info->sock);
#endif
}
bool setup(sock_info* info)
{
char Buffer[512] = {0};
const char* address_str = info->address;
struct sockaddr_in* sockaddr_ipv4 = NULL;
if (strncasecmp
(address_str
, "inaddr_any", min
(strlen(info
->address
), 10))) {
address_str = GetHostLocation(Buffer, info);
struct addrinfo* it = NULL, *result = NULL;
getaddrinfo(address_str, NULL, NULL, &result);
for (it = result; it != NULL; it = it->ai_next)
{
sockaddr_ipv4 = (struct sockaddr_in*)it->ai_addr;
address_str = inet_ntoa(sockaddr_ipv4->sin_addr);
if (strncmp(address_str
, "0.0.0.0", 7)) break;
}
freeaddrinfo(result);
}
if ((info->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
return false;
}
struct sockaddr_in SockAddr;
memset(&SockAddr
, 0, sizeof(SockAddr
)); SockAddr.sin_port = htons(info->port);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = (!strncasecmp(address_str, "inaddr_any", 10) ? htonl(INADDR_ANY) : inet_addr(address_str));
if (connect(info->sock, (struct sockaddr*)&SockAddr, sizeof(SockAddr)) < 0)
{
return false;
}
return true;
}
void CreateGetHeader(char* buffer, sock_info* info)
{
const char* header =
{
"Connection: close\r\n"\
"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11\r\n"\
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"Accept-Language: en-US,en;q=0.8\r\n"\
"Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7\r\n"\
"Cache-Control: no-cache\r\n"
};
const char* Request = "GET /%s HTTP/1.1\r\n"\
"Host: %s\r\n"\
"%s\r\n";
char HostBuffer[512] = {0};
sprintf(buffer
, Request
, GetRequestLocation
(NULL
, info
), GetHostLocation
(HostBuffer
, info
), header
); }
int main()
{
sock_info info = {0, "http://stackoverflow.com/questions/tagged/c%2b%2b", 80};
if (init())
{
if (setup(&info))
{
char RequestBuffer[1024] = {0};
CreateGetHeader(RequestBuffer, &info);
send
(info.
sock, RequestBuffer
, strlen(RequestBuffer
), 0); memset(&RequestBuffer
, 0, sizeof(RequestBuffer
));
recv(info.sock, &RequestBuffer[0], sizeof(RequestBuffer), 0);
int bytes_read = 0;
while(true)
{
int read = recv(info.sock, RequestBuffer, sizeof(RequestBuffer), 0);
if (read <= 0)
break;
RequestBuffer[read] = NULL;
bytes_read += read;
if (bytes_read >= 88500)
break;
memset(RequestBuffer
, 0, sizeof(RequestBuffer
)); }
}
destroy(&info);
}
return 0;
}
I2lmIGRlZmluZWQgX1dJTjMyIHx8IGRlZmluZWQgX1dJTjY0CiNpbmNsdWRlIDx3aW5zb2NrMi5oPgojaW5jbHVkZSA8d3MydGNwaXAuaD4KI2luY2x1ZGUgPHdpbmRvd3MuaD4KI2Vsc2UKI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CiNpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNkZWZpbmUgbWluKGEsIGIpICgoKGEpPChiKSk/KGEpOihiKSkKI2RlZmluZSBtYXgoYSwgYikgKCgoYSk+KGIpKT8oYSk6KGIpKQoKI2lmbmRlZiBfX2NwbHVzcGx1cwp0eXBlZGVmIGVudW0ge2ZhbHNlLCB0cnVlfSBib29sOwojZW5kaWYKCnR5cGVkZWYgc3RydWN0CnsKICAgIGludCBzb2NrOwogICAgY29uc3QgY2hhciogYWRkcmVzczsKICAgIHVuc2lnbmVkIHNob3J0IHBvcnQ7Cn0gc29ja19pbmZvOwoKCmNvbnN0IGNoYXIqIEdldEhvc3RMb2NhdGlvbihjaGFyKiBCdWZmZXIsIHNvY2tfaW5mbyogaW5mbykKewogICAgY29uc3QgY2hhciogYWRkciA9IHN0cnN0cihpbmZvLT5hZGRyZXNzLCAiOi8vIik7CgogICAgaWYgKGFkZHIpCiAgICAgICAgc3RyY3B5KEJ1ZmZlciwgYWRkciArIDMpOwoKICAgIGlmICgoYWRkciA9IHN0cnN0cihCdWZmZXIsICIvIikpKQogICAgICAgIEJ1ZmZlclthZGRyIC0gQnVmZmVyXSA9ICdcMCc7CgogICAgcmV0dXJuIGFkZHIgPyBCdWZmZXIgOiBOVUxMOwp9Cgpjb25zdCBjaGFyKiBHZXRSZXF1ZXN0TG9jYXRpb24oY2hhciogQnVmZmVyLCBzb2NrX2luZm8qIGluZm8pCnsKICAgIGNvbnN0IGNoYXIqIGFkZHIgPSBzdHJzdHIoaW5mby0+YWRkcmVzcywgIjovLyIpOwoKICAgIGlmIChCdWZmZXIpCiAgICB7CiAgICAgICAgaWYgKGFkZHIpCiAgICAgICAgICAgIHN0cmNweShCdWZmZXIsIGFkZHIgKyAzKTsKCiAgICAgICAgaWYgKChhZGRyID0gc3Ryc3RyKEJ1ZmZlciwgIi8iKSkpCiAgICAgICAgewogICAgICAgICAgICBzdHJjcHkoQnVmZmVyLCBhZGRyICsgMSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGFkZHIgPSBzdHJzdHIoYWRkciArIDMsICIvIik7CiAgICAgICAgcmV0dXJuIGFkZHIgPyBhZGRyICsgMSA6IE5VTEw7CiAgICB9CgogICAgcmV0dXJuIGFkZHIgPyBCdWZmZXIgOiBOVUxMOwp9Cgpib29sIGluaXQoKQp7CiAgICAjaWYgZGVmaW5lZCBfV0lOMzIgfHwgZGVmaW5lZCBfV0lONjQKICAgIFdTQURBVEEgd3NhRGF0YSA9IHswfTsKICAgIHJldHVybiAhV1NBU3RhcnR1cChNQUtFV09SRCgyLCAyKSwgJndzYURhdGEpOwogICAgI2Vsc2UKICAgIHJldHVybiB0cnVlOwogICAgI2VuZGlmCn0KCnZvaWQgZGVzdHJveShzb2NrX2luZm8qIGluZm8pCnsKICAgICNpZiBkZWZpbmVkIF9XSU4zMiB8fCBkZWZpbmVkIF9XSU42NAogICAgc2h1dGRvd24oaW5mby0+c29jaywgU0RfQk9USCk7CiAgICBjbG9zZXNvY2tldChpbmZvLT5zb2NrKTsKICAgIFdTQUNsZWFudXAoKTsKICAgICNlbHNlCiAgICBzaHV0ZG93bihpbmZvLT5zb2NrLCBTSFVUX1JEV1IpOwogICAgY2xvc2UoaW5mby0+c29jayk7CiAgICAjZW5kaWYKfQoKYm9vbCBzZXR1cChzb2NrX2luZm8qIGluZm8pCnsKICAgIGNoYXIgQnVmZmVyWzUxMl0gPSB7MH07CiAgICBjb25zdCBjaGFyKiBhZGRyZXNzX3N0ciA9IGluZm8tPmFkZHJlc3M7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4qIHNvY2thZGRyX2lwdjQgPSBOVUxMOwoKICAgIGlmIChzdHJuY2FzZWNtcChhZGRyZXNzX3N0ciwgImluYWRkcl9hbnkiLCBtaW4oc3RybGVuKGluZm8tPmFkZHJlc3MpLCAxMCkpKQogICAgewogICAgICAgIGFkZHJlc3Nfc3RyID0gR2V0SG9zdExvY2F0aW9uKEJ1ZmZlciwgaW5mbyk7CgogICAgICAgIHN0cnVjdCBhZGRyaW5mbyogaXQgPSBOVUxMLCAqcmVzdWx0ID0gTlVMTDsKICAgICAgICBnZXRhZGRyaW5mbyhhZGRyZXNzX3N0ciwgTlVMTCwgTlVMTCwgJnJlc3VsdCk7CiAgICAgICAgZm9yIChpdCA9IHJlc3VsdDsgaXQgIT0gTlVMTDsgaXQgPSBpdC0+YWlfbmV4dCkKICAgICAgICB7CiAgICAgICAgICAgIHNvY2thZGRyX2lwdjQgPSAoc3RydWN0IHNvY2thZGRyX2luKilpdC0+YWlfYWRkcjsKICAgICAgICAgICAgYWRkcmVzc19zdHIgPSBpbmV0X250b2Eoc29ja2FkZHJfaXB2NC0+c2luX2FkZHIpOwoKICAgICAgICAgICAgaWYgKHN0cm5jbXAoYWRkcmVzc19zdHIsICIwLjAuMC4wIiwgNykpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgZnJlZWFkZHJpbmZvKHJlc3VsdCk7CiAgICB9CgogICAgaWYgKChpbmZvLT5zb2NrID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfU1RSRUFNLCBJUFBST1RPX1RDUCkpIDwgMCkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgc3RydWN0IHNvY2thZGRyX2luIFNvY2tBZGRyOwogICAgbWVtc2V0KCZTb2NrQWRkciwgMCwgc2l6ZW9mKFNvY2tBZGRyKSk7CiAgICBTb2NrQWRkci5zaW5fcG9ydCA9IGh0b25zKGluZm8tPnBvcnQpOwogICAgU29ja0FkZHIuc2luX2ZhbWlseSA9IEFGX0lORVQ7CiAgICBTb2NrQWRkci5zaW5fYWRkci5zX2FkZHIgPSAoIXN0cm5jYXNlY21wKGFkZHJlc3Nfc3RyLCAiaW5hZGRyX2FueSIsIDEwKSA/IGh0b25sKElOQUREUl9BTlkpIDogaW5ldF9hZGRyKGFkZHJlc3Nfc3RyKSk7CgogICAgaWYgKGNvbm5lY3QoaW5mby0+c29jaywgKHN0cnVjdCBzb2NrYWRkciopJlNvY2tBZGRyLCBzaXplb2YoU29ja0FkZHIpKSA8IDApCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHJldHVybiB0cnVlOwp9Cgp2b2lkIENyZWF0ZUdldEhlYWRlcihjaGFyKiBidWZmZXIsIHNvY2tfaW5mbyogaW5mbykKewogICAgY29uc3QgY2hhciogaGVhZGVyID0KICAgIHsKICAgICAgICAiQ29ubmVjdGlvbjogY2xvc2VcclxuIlwKICAgICAgICAiVXNlci1BZ2VudDogTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgNi4xOyBXT1c2NCkgQXBwbGVXZWJLaXQvNTM3LjExIChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzIzLjAuMTI3MS45NyBTYWZhcmkvNTM3LjExXHJcbiJcCiAgICAgICAgIkFjY2VwdDogdGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksKi8qO3E9MC44XHJcbiIKICAgICAgICAiQWNjZXB0LUxhbmd1YWdlOiBlbi1VUyxlbjtxPTAuOFxyXG4iXAogICAgICAgICJBY2NlcHQtQ2hhcnNldDogSVNPLTg4NTktMSxVVEYtODtxPTAuNywqO3E9MC43XHJcbiJcCiAgICAgICAgIkNhY2hlLUNvbnRyb2w6IG5vLWNhY2hlXHJcbiIKICAgIH07CgogICAgY29uc3QgY2hhciogUmVxdWVzdCA9ICJHRVQgLyVzIEhUVFAvMS4xXHJcbiJcCiAgICAgICAgICAgICAgICAgICAgICAgICAiSG9zdDogJXNcclxuIlwKICAgICAgICAgICAgICAgICAgICAgICAgICIlc1xyXG4iOwoKICAgIGNoYXIgSG9zdEJ1ZmZlcls1MTJdID0gezB9OwogICAgc3ByaW50ZihidWZmZXIsIFJlcXVlc3QsIEdldFJlcXVlc3RMb2NhdGlvbihOVUxMLCBpbmZvKSwgR2V0SG9zdExvY2F0aW9uKEhvc3RCdWZmZXIsIGluZm8pLCBoZWFkZXIpOwp9CgppbnQgbWFpbigpCnsKICAgIHNvY2tfaW5mbyBpbmZvID0gezAsICJodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zL3RhZ2dlZC9jJTJiJTJiIiwgODB9OwoKICAgIGlmIChpbml0KCkpCiAgICB7CiAgICAgICAgaWYgKHNldHVwKCZpbmZvKSkKICAgICAgICB7CiAgICAgICAgICAgIGNoYXIgUmVxdWVzdEJ1ZmZlclsxMDI0XSA9IHswfTsKICAgICAgICAgICAgQ3JlYXRlR2V0SGVhZGVyKFJlcXVlc3RCdWZmZXIsICZpbmZvKTsKICAgICAgICAgICAgc2VuZChpbmZvLnNvY2ssIFJlcXVlc3RCdWZmZXIsIHN0cmxlbihSZXF1ZXN0QnVmZmVyKSwgMCk7CiAgICAgICAgICAgIG1lbXNldCgmUmVxdWVzdEJ1ZmZlciwgMCwgc2l6ZW9mKFJlcXVlc3RCdWZmZXIpKTsKCiAgICAgICAgICAgIHJlY3YoaW5mby5zb2NrLCAmUmVxdWVzdEJ1ZmZlclswXSwgc2l6ZW9mKFJlcXVlc3RCdWZmZXIpLCAwKTsKICAgICAgICAgICAgcHJpbnRmKCIlcyIsIFJlcXVlc3RCdWZmZXIpOwoKICAgICAgICAgICAgaW50IGJ5dGVzX3JlYWQgPSAwOwoKICAgICAgICAgICAgd2hpbGUodHJ1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IHJlYWQgPSByZWN2KGluZm8uc29jaywgUmVxdWVzdEJ1ZmZlciwgc2l6ZW9mKFJlcXVlc3RCdWZmZXIpLCAwKTsKICAgICAgICAgICAgICAgIGlmIChyZWFkIDw9IDApCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgUmVxdWVzdEJ1ZmZlcltyZWFkXSA9IE5VTEw7CiAgICAgICAgICAgICAgICBwcmludGYoIiVzIiwgUmVxdWVzdEJ1ZmZlcik7CgogICAgICAgICAgICAgICAgYnl0ZXNfcmVhZCArPSByZWFkOwoKICAgICAgICAgICAgICAgIGlmIChieXRlc19yZWFkID49IDg4NTAwKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIG1lbXNldChSZXF1ZXN0QnVmZmVyLCAwLCBzaXplb2YoUmVxdWVzdEJ1ZmZlcikpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBkZXN0cm95KCZpbmZvKTsKICAgIH0KCiAgICByZXR1cm4gMDsKfQo=