#include <winsock2.h>
#include <windows.h>
#include <string>
#include <iostream>
#include <cstring>
#pragma comment(lib, "ws2_32.lib")
char* parse_url(char* d, const char* url);
int ReadUrl(const char* url, std::string& dst, DWORD msec = WSA_INFINITE);
int main(void){
WSADATA wd = {0};
if(WSAStartup(MAKEWORD(2, 2), &wd) != 0)
return EXIT_FAILURE;
std::string buf;
char url[] = "http://mysite.ru/version.txt";
int err = ::ReadUrl(url, buf, 12000);
if(err == ERROR_SUCCESS)
std::cout << buf;
else
std::cerr << "error, code: " << err;
std::cout << std::endl;
WSACleanup();
std::cin.get();
return 0;
}
int ReadUrl(const char* url, std::string& dst, DWORD msec){
int ret;
char host[64];
SOCKET sock;
WSAEVENT hevent;
if(! *parse_url(host, url))
return WSAEFAULT;
hevent = WSACreateEvent();
if(hevent == WSA_INVALID_EVENT)
return WSAGetLastError();
// создаём сокет
sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP,
NULL, 0, WSA_FLAG_OVERLAPPED);
if(sock == INVALID_SOCKET){
ret = WSAGetLastError();
WSACloseEvent(hevent);
return ret;
}
//получаем IP
hostent* phost = gethostbyname(host);
if(phost == NULL){
ret = WSAGetLastError();
WSACloseEvent(hevent);
closesocket(sock);
return ret;
}
sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
CopyMemory(&addr.sin_addr, phost->h_addr_list[0], phost->h_length);
// коннектимся к хосту
ret = connect(sock, (const sockaddr*)&addr, sizeof(addr));
if(ret == SOCKET_ERROR) {
ret = WSAGetLastError();
WSACloseEvent(hevent);
closesocket(sock);
return ret;
}
// задаём запрос
dst = "GET ";
dst += url;
dst += "\r\n\r\n";
ret = send(sock, &dst[0], dst.length(), 0);
dst = "";
Sleep(50);
if(ret == SOCKET_ERROR) {
ret = WSAGetLastError();
WSACloseEvent(hevent);
closesocket(sock);
return ret;
}
//***
WSAOVERLAPPED wso;
WSABUF wbuf;
DWORD len, flag;
char buf[512];
wbuf.buf = &buf[0];
wbuf.len = sizeof(buf) - 1;
//чтение
while(1){
ZeroMemory(&wso, sizeof(wso));
wso.hEvent = hevent;
len = flag = 0;
ret = WSARecv(sock, &wbuf, 1, &len, &flag, &wso, NULL);
if(ret == SOCKET_ERROR){
if((ret = WSAGetLastError()) != WSA_IO_PENDING)
break;
}
ret = WSAWaitForMultipleEvents(1, &hevent, FALSE, msec, FALSE);
if((ret == WSA_WAIT_FAILED) || (ret == WSA_WAIT_TIMEOUT)){
ret = (! dst.length()) ? SOCKET_ERROR : 0;
break;
}
WSAResetEvent(hevent);
ret -= WSA_WAIT_EVENT_0;
if(ret < 0 || ret > 0){
ret = (! dst.length()) ? SOCKET_ERROR : 0;
break;
}
len = 0;
ret = WSAGetOverlappedResult(sock, &wso, &len, FALSE, &flag);
if((! len) || (! ret)){
if((ret = WSAGetLastError()) != WSA_IO_INCOMPLETE)
break;
continue;
}
if(len > 0){
buf[len] = '\0';
dst.append(buf, buf + len);
}
}
WSASetEvent(hevent);
WSACloseEvent(hevent);
closesocket(sock);
return (ret == SOCKET_ERROR) ? WSAGetLastError() : ERROR_SUCCESS;
}
char* parse_url(char* d, const char* url){
char* t = d;
if(! strnicmp(url, "http://", 7))
url += 7;
while(*url && (*url != '/'))
*d++ = *url++;
*d = '\0';
return t;
}