Da hab ich noch was...
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "D:\lib\socket.h"
string Url, Host, Protocol, Request, Received, Name;
int Base, Port = 80;
SocketClient Client;
int isHeader = 1, Length = 99, Bytes = 1, Rcvd = 0;
string GetFilename(string str)
{
int i = str.length();
while(1 > 0)
{
if (str.substr(i, 1).compare("/") == 0)
{
break;
}
i--;
}
return str.substr(i + 1);
}
void ParseData()
{
Host = Url.substr(Base + 3, Url.find("/", Base + 4) - Base - 3);
if (Host.find(":") != -1)
{
Port = atoi(Host.substr(Host.find(":") + 1).c_str());
Host = Host.substr(0, Host.find(":"));
if (Port == 0)
{
printf("Invalid port value.\n");
exit(0);
}
}
Request = "";
if (Url.length() > Url.substr(0, Url.find("/", Base + 4) - Base - 3).length())
{
Request = Url.substr(Url.find("/", Base + 4));
Name = GetFilename(Request);
}
if (Name.length() == 0)
{
Name = "index.html";
}
printf("---------------------\n");
printf("Protocol: %s\n", Protocol.c_str());
printf("Host: %s\n", Host.c_str());
printf("Port: %d\n", Port);
printf("Request: %s\n", Request.c_str());
printf("Filename: %s\n", Name.c_str());
printf("---------------------\n\n");
}
int SendHttpRequest(int Retrys)
{
Client >> "GET ";
Client >> Request.c_str();
Client >> " HTTP/1.1\n";
Client >> "Host: ";
Client >> Host.c_str();
Client >> "\nConnection: Close\n\n";
fstream fStream;
fStream.open(Name.c_str(), fstream::out | fstream::binary);
while(Rcvd < Bytes)
{
Length = Client.ReceiveLine(Received);
if (isHeader == 1)
{
printf("%s\n", Received.c_str());
}
if (isHeader == 1 && Received.find("Content-Length") != -1)
{
Bytes = atoi(Received.substr(15).c_str());
}
//Location: http://www.google.de/
if (isHeader == 1 && Received.find("Location") != -1 && Retrys > 0)
{
Retrys--;
fStream.close();
Url = Received.substr(10);
ParseData();
return SendHttpRequest(Retrys);
}
else if (isHeader == 1 && Received.find("Location") != -1 && Retrys <= 0)
{
fStream.close();
return -1;
}
if (isHeader == 0)
{
Rcvd += sizeof(Received.c_str());
fStream.write((Received + '\n').c_str(), (Received + '\n').length());
}
else if (Length < 2)
{
isHeader = 0;
}
if (Received.empty() == true)
{
continue;
}
//printf("%s\n", Received.c_str());
}
fStream.close();
return 0;
}
int main(int argc, char* argv[])
{
printf("WGET -by BlackBerry\n\n");
if (argc == 1)
{
printf("Syntax: %s <url>\n", argv[0]);
exit(0);
}
Url = argv[1];
if (Url.find("://") == -1)
{
printf("Please define a protocol.\n");
exit(0);
}
Base = Url.find("://");
Protocol = Url.substr(0, Base);
ParseData();
if (Protocol.compare("http") == 0)
{
Client.Connect((char*) Host.c_str(), Port);
if (Client.IsConnected())
{
if (SendHttpRequest(5) == -1)
{
printf("Not able to get content\n");
}
}
else
{
printf("Could not reach host.\n");
}
Client.Close();
}
else
{
printf("Protocol [%s] not supported.\n", Protocol.c_str());
}
return 0;
}
socket.h
Code:
/*
C++ TCP Socket[Server|Client] Header By BlackBerry
Tested on Windows XP™ and Windows Vista™ and Linux Ubuntu 8.04.
Compiler: G++ (on Ubuntu and the by Dev-C++ adapted version).
Inspirated by a socketclass published by René Nyffenegger
on www.adp-gmbh.ch and based on code found on www.c-worker.ch.
This header file is free software.
You can modify this file in any way you want.
Hopefully this is usefull in some way.
For more information, please E-Mail me [src.blackberry@yahoo.com]
Special thanks to Lee for helping and optimizing the code.
The #pragma comment(a, "libwsock32.a") should include the needed library,
but if it doesn't you might have to include it manually
Dev-C++:
Project > Project Options > Parameter > Linker > Add Library
#define DEBUG_MODE to be verbose (display all data received/written from/to socket)
And finally a bit of optimization. I do not know how far your compiler optimizes
the code (like not compiling not-used classes or function) so here is a little addon:
#define NO_SOCKET_SERVER to not compile the SocketServer-class
#define NO_SOCKET_CLIENT to not compile the SocketClient-class
*/
// #define DEBUG_MODE
// #define NO_SOCKET_SERVER
// #define NO_SOCKET_CLIENT
#ifndef SOCKET_H_V2
#define SOCKET_H_V2
#ifdef DEBUG_MODE
#include <cstdio>
#endif
#include <string>
#ifdef _WIN32
#include <winsock2.h>
#pragma comment(lib, "libws2_32")
#define close(x) closesocket(x)
typedef int socklen_t;
#else
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <netdb.h>
#endif
using namespace std;
#ifdef DEBUG_MODE
void DEBUG_WRITE_LOG(string str)
{
if (str.substr(str.length() - 1).compare("\n") == 0)
{
printf(">> %s", str.c_str());
}
else
{
printf(">> %s\n", str.c_str());
}
}
void DEBUG_WRITE_LOG(char* c_str)
{
string str(c_str);
DEBUG_WRITE_LOG(str);
}
#endif
#ifndef NO_SOCKET_SERVER
class SocketServer
{
private:
int sockListen;
struct sockaddr_in addr;
struct sockaddr_in clientinfo;
public:
SocketServer(){}
SocketServer(int port, int pending = 5)
{
StartServer(port, pending);
}
void StartServer(int port, int pending = 5)
{
long rc;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
#ifdef _WIN32
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
{
return (void) NULL;
}
#endif
sockListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
bind(this->sockListen, (struct sockaddr*) &addr, sizeof(addr));
listen(this->sockListen, pending);
}
void WSAStartServer(int port, int pending = 5)
{
#ifdef _WIN32
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
#ifdef _WIN32
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
{
return (void) NULL;
}
#endif
sockListen = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
bind(this->sockListen, (struct sockaddr*) &addr, sizeof(addr));
listen(this->sockListen, pending);
#else
StartServer(port, pending);
#endif
}
int Accept()
{
int addrlen = sizeof(clientinfo);
return accept(this->sockListen, (struct sockaddr*) &clientinfo, (socklen_t*) &addrlen);
}
char* Accept(int &socket)
{
int addrlen = sizeof(clientinfo);
socket = accept(this->sockListen, (struct sockaddr*) &clientinfo, (socklen_t*) &addrlen);
return GetClientIP();
}
char* GetClientIP()
{
return (char*) inet_ntoa(clientinfo.sin_addr);
}
short GetClientPort()
{
return ntohs(clientinfo.sin_port);
}
int Socket()
{
return this->sockListen;
}
void Shutdown()
{
close(this->sockListen);
}
};
class UDPSocketServer
{
private:
int sockListen;
struct sockaddr_in addr;
public:
UDPSocketServer(){}
UDPSocketServer(int port)
{
StartServer(port);
}
void StartServer(int port)
{
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
#ifdef _WIN32
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
{
return (void) NULL;
}
#endif
sockListen = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
bind(this->sockListen, (struct sockaddr*) &addr, sizeof(addr));
}
};
#endif
#ifndef NO_SOCKET_CLIENT
class SocketClient
{
private:
int cSock;
struct sockaddr_in addr;
public:
SocketClient(){}
SocketClient(int socket)
{
this->cSock = socket;
}
SocketClient(const char* host, int port)
{
Connect((char*) host, port);
}
SocketClient(char* host, int port)
{
Connect(host, port);
}
int Connect(char* host, int port)
{
#ifdef _WIN32
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
{
return 1;
}
#endif
this->cSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (this->cSock == -1)
{
return 2;
}
char ipaddr[20];
hostent *dns = gethostbyname(host);
sprintf(ipaddr, "%u.%u.%u.%u", (unsigned char) dns->h_addr_list[0][0], (unsigned char) dns->h_addr_list[0][1], (unsigned char) dns->h_addr_list[0][2], (unsigned char) dns->h_addr_list[0][3]);
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr(ipaddr);
server.sin_port = htons(port);
server.sin_family = AF_INET;
if(connect(this->cSock, (struct sockaddr*) &server, sizeof(server)) != 0)
{
return 3;
}
return 0;
}
int Socket()
{
return this->cSock;
}
void operator=(int Socket)
{
if (send(Socket, NULL, 0, 0) != -1)
{
this->cSock = Socket;
}
}
int operator==(int Socket)
{
if (this->cSock == Socket)
{
return 1;
}
return 0;
}
long operator>>(const char* msg)
{
#ifdef DEBUG_MODE
DEBUG_WRITE_LOG(msg);
#endif
return send(this->cSock, msg, strlen(msg), 0);
}
string ReceiveTo(char stopChar, int stopLength = 0)
{
string ret;
char r;
while(1)
{
switch(recv(this->cSock, &r, 1, 0))
{
case 0:
return ret;
case -1:
return "";
}
if ((r == stopChar && stopChar != '\0') || (ret.length() == stopLength && stopLength > 0))
{
#ifdef DEBUG_MODE
DEBUG_WRITE_LOG(ret);
#endif
return ret;
}
ret += r;
}
}
string operator<<(int stopLength)
{
return ReceiveTo('\0', stopLength);
}
string ReceiveLine()
{
return ReceiveTo('\n', 0);
}
int ReceiveLine(string &str)
{
str = ReceiveTo('\n', 0);
return str.length();
}
int IsConnected()
{
if (send(this->cSock, NULL, 0, 0) == -1)
{
return 0;
}
return 1;
}
void Close()
{
close(this->cSock);
}
};
#endif
#endif
Syntax ist im Programm beschrieben - programm <url>
Einfach über eine Batch datei ausführen, oder gleich das originale GNU wget runterladen (funktioniert auch auf Windows)