// clientv01.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "clientv01.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// The one and only application object
CWinApp theApp;
using namespace std;
int startPos = 0;
void ParseUrl(char url[512], char servername[512], char filepath[512], char filename[100])
{
int j = 0;
bool error = false;
int temp = 0;
for (int i = 0;i< 512;)
{
if (url[j] == 0)
{
error = true;
break;
}
if (url[j] == 47)
{
temp++;
if (temp == 3)
{
break;
}
}
else
{
if (temp > 1)
{
servername = url[j];
i++;
}
}
j++;
}
for (int i = 0;i< 512;i++)
{
if (url[j] == 0)
{
break;
}
filepath = url[j];
j++;
}
int count = 0;
for (int i = 0; i< 512;i++)
{
j--;
if (url[j] == 47)
{
break;
}
count++;
}
j++;
filename[0] = 99;
filename[1] = 58;
filename[2] = 92;
for (int i = 3;count>0;i++)
{
filename = url[j];
j++;
count--;
}
}
int examineBuff(char buff[512],bool mode)
{
char temp[100] = "";
temp[0] = buff[9];
temp[1] = buff[10];
temp[2] = buff[11];
temp[3] = 32;
int i;
for (i = 4;;i++)
{
if (buff[i+9] != 13)
{
temp = buff[i+9];
}
else
{
break;
}
}
i = i+9;
cout << "Status: " << temp << endl;
cout << "If you have any questions about the status, note down the details of the previouse line and contact Neil Stevenson\n";
if (temp[0] == 52 || temp[0] == 53)
{
return 0;
}
if (temp[0] == 51)
{
return 0;
}
if (mode) return 1;
if (!mode)
{
for (int j = 0;j<100;j++)
{
temp[j] = 0;
}
while (true)
{
i+=2;
if (buff == 13 && buff[i+1] == 10)
{
startPos = i+2;
return 1;
}
for(int j = 0;j < 19 ;i++)
{
if (buff == 13)
{
break;
}
temp[j] = buff;
j++;
}
if (strcmp(temp,"Transfer-Encoding:") == 0)
{
for (int j = 0;j<100;j++)
{
temp[j] = 0;
}
i++;
for(int j = 0;;i++)
{
if (buff != 13)
{
temp[j] = buff;
}
else
{
break;
}
}
if (strcmp(temp,"chunked") == 0)
{
return 2;
}
}
for (int j = 0;j<100;j++)
{
temp[j] = 0;
}
while(buff != 13)
{
i++;
}
}
}
return 1;
}
bool client(char url[512],const char *hostname,char filepath[512], char filename[100],bool proxy,char proxyadd[512],short proxyport)
{
CFile f;
SOCKET c;
char buff[512] = "";
int chrecv = 0;
int type = 0;
WSADATA info;
if (WSAStartup(0x101,&info)!=0)
{
cout << "ERROR seting up winsock\n";
return false;
}
c = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
struct hostent *hp;
struct sockaddr_in sa;
if (c == INVALID_SOCKET)
{
cout << "Invalid socket\n";
return false;
}
cout << "set up socket\n";
if (proxy)
{
if (inet_addr(proxyadd) == INADDR_NONE)
{
hp = gethostbyname(proxyadd);
}
else
{
unsigned int addr = inet_addr(proxyadd);
hp = gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
}
}
else
{
if (inet_addr(hostname) == INADDR_NONE)
{
hp = gethostbyname(hostname);
}
else
{
unsigned int addr = inet_addr(hostname);
hp = gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
}
}
if (hp == NULL)
{
cout << "Error getting host info\n";
closesocket(c);
return false;
}
cout << "Got host info\n";
sa.sin_addr.s_addr = *((unsigned long*)hp->h_addr);
sa.sin_family = AF_INET;
sa.sin_port = htons(80);
if (connect(c,(struct sockaddr*)&sa,sizeof(sa)))
{
cout << "Error connecting\n";
return false;
}
if (proxy)
{
cout << "connected to proxy\n";
sprintf(buff,"CONNECT %s:%s http/1.1\r\nHOST: %s\r\nCONNECTION: close\r\n\r\n",hostname,proxyport,hostname);
send(c,buff,(int)strlen(buff),0);
for (int j = 0;j<512;j++)
{
buff[j] = 0;
}
if (recv(c,buff,500,0) < 1)
{
cout << "Error, no reply from server\n" << WSAGetLastError() << endl;
closesocket(c);
return 0;
}
if (examineBuff(buff,true) == 1)
{
cout << "Connected to server.\n";
}
else
{
cout << "error connecting to server.\n";
closesocket(c);
return 0;
}
}
else
{
cout << "connected\n";
}
cout << "requesting file\n";
for (int j = 0;j<512;j++)
{
buff[j] = 0;
}
if (proxy)
{
sprintf(buff,"GET %s HTTP/1.1\r\nHOST: %s\r\nConnection: close\r\n\r\n ",url,hostname);
}
else
{
sprintf(buff,"GET %s HTTP/1.1\r\nHOST: %s\r\nConnection: close\r\n\r\n ",filepath,hostname);
}
send(c,buff,(int)strlen(buff),0);
for (int j = 0;j<512;j++)
{
buff[j] = 0;
}
int t = 0;
t = recv(c,buff,500,0);
cout << buff << endl;
if (t == -1)
{
cout << "Error, no reply from server\n" << WSAGetLastError() << endl;
closesocket(c);
return 0;
}
type = examineBuff(buff,false);
if (type == 0)
{
closesocket(c);
return 0;
}
f.Open(filename,CFile::modeCreate | CFile::modeWrite);
cout << "writting\n";
int notify = 2;
if (type == 1)
{
for (int i = startPos;i<512;i++)
{
if (buff == 0) break;
char temp[1];
temp[0] = buff;
f.Write(temp,1);
chrecv +=1;
}
do
{
for (int j = 0;j<512;j++)
{
buff[j] = 0;
}
t = recv(c,buff,400,0);
chrecv += t;
if (t!= 0)
{
f.Write(buff,t);
}
if (chrecv/1024 > notify)
{
cout << chrecv/1024 << "kb downloaded\n";
notify += 2;
}
}while (t!=0);
}
cout << "File downloaded, size = " << (float)chrecv/1024 << "kb\n";
cout << "located: " << filename << "\n";
f.Close();
closesocket(c);
return true;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
return nRetCode;
}
char url[512] = "", servername[512] = "",filepath[512] = "",filename[100] = "";
char proxyadd[512] = "";
short proxyport = 0;
bool proxy = true;
cout << "Enter the proxy address, if you are not using a proxy enter 0\n";
cin.getline(proxyadd,512);
if (proxyadd[0] == 48)
{
proxy = false;
}
if (proxy)
{
cout << "Enter Proxy port.\n";
cin >> proxyport;
}
cout << "Enter url of file, start with http:// and include extension.\nEG. http://www.test.com/get/this/file.exe\n";
cin.getline(url,512);
ParseUrl(url,servername,filepath,filename);
// ParseUrl("http://www.geocities.com/andrew_parlane2000/penguin.gif",servername,filepath,filename);
// ParseUrl("http://www.plus-america.com/images/zipped/v3_highres_briefcase.zip",servername,filepath,filename);
client(url,servername,filepath,filename,proxy,proxyadd,proxyport);
WSACleanup();
cout << "Thank you for using file downloader.\n";
cout << "Created by Neil Stevenson\n";
cout << "Press any key to quit.\n";
_getch();
return nRetCode;
}
winsock - send recieve - c++
I am making a prog that downloads files from the internet. you enter url, and it connects to server and recieves the responce and the file. when I try to download winzip 9 i get 2,417,599 bytes but when i dl it off IE i get 2,417,824 bytes. Im not sure whats wrong, but its starting to annoy me. here is the code, its quite big and nasty code, but its nowhere near finished. Also Im trying to allow the user to connect through a proxy, but I havn't had chance to test it yet. edit: the code you probably want to look at is the client function. seccond to bottom.
www.stickskate.com -> check it out, some gnarly stick skating movies
Open the files up in a hex editor (or open up the first 30 kilobytes in notepad). You'll probably see what the problem is.
enum Bool { True, False, FileNotFound };
I have allready done that.
But I did it again anyway, here is what I found. I have the first three bytes correct, then I miss 225 bytes and its ok from there. now I have to wotrk out why. hereis some pseudo of what my code does.
connects and sorts
swend request
read 510 bytes
examine headers
if not ok exit
write any bytes left in the first lot of data(that is not headers) to the
loop
file, revieve another 510 bytes, write this to file
next
finish
So I guess, the first three bytes, come from the first lot of data, then I miss a bit. Im not sure why. Could it be that in the time im examing the headers, I missed the next lot of data. If so, how come I get the same file size every time.
oh, and thanks for the help, you put me on the write track.
But I did it again anyway, here is what I found. I have the first three bytes correct, then I miss 225 bytes and its ok from there. now I have to wotrk out why. hereis some pseudo of what my code does.
connects and sorts
swend request
read 510 bytes
examine headers
if not ok exit
write any bytes left in the first lot of data(that is not headers) to the
loop
file, revieve another 510 bytes, write this to file
next
finish
So I guess, the first three bytes, come from the first lot of data, then I miss a bit. Im not sure why. Could it be that in the time im examing the headers, I missed the next lot of data. If so, how come I get the same file size every time.
oh, and thanks for the help, you put me on the write track.
www.stickskate.com -> check it out, some gnarly stick skating movies
If I recall correct, the data is buffered after receiving until you call recv().
I have no idea how HTTP does it, but I suggest you upload a small textfile somewhere(Your ISP, or perhaps some webspace somewhere else), and try to download that file. At this point, you can use the debugger to examine the data that's coming in.
As you know the exact contents of the text file, you can see what data doesn't belong in there, and what data is missing. After you figured out what's wrong you can try it on the winzip file.
Toolmaker
I have no idea how HTTP does it, but I suggest you upload a small textfile somewhere(Your ISP, or perhaps some webspace somewhere else), and try to download that file. At this point, you can use the debugger to examine the data that's coming in.
As you know the exact contents of the text file, you can see what data doesn't belong in there, and what data is missing. After you figured out what's wrong you can try it on the winzip file.
Toolmaker
Also, code for parsing a HTTP GET result can be found in my tiny http-get utility. It uses straight sockets, and doesn't work through proxies, but the response parsing should be the same.
enum Bool { True, False, FileNotFound };
thanks for the link, I will look through it and post my results.
I have tried the read txt file thig, but here is a small prob:
I recieve the some data the '10' or newline, when i write this to the file, it appears as a square. When checking the original file, all the 10 were preceeded with 13 'carriage return'. but when downloading, i dont recieve the 13 just the 10. Im confused why. any ideas.
I have tried the read txt file thig, but here is a small prob:
I recieve the some data the '10' or newline, when i write this to the file, it appears as a square. When checking the original file, all the 10 were preceeded with 13 'carriage return'. but when downloading, i dont recieve the 13 just the 10. Im confused why. any ideas.
www.stickskate.com -> check it out, some gnarly stick skating movies
here is the problem, I got it eventually.
here is what it should be
simple enough, but an annoying error. Just downloaded a 7mb file perfectly. I have also integrated support for proxys (I hope) I have to test it tommorow.
I still need to include code to deal with a moved file, or a 100 continued status code. and also chunked data. When I have done that, I will maybe implement a html viewer into it, and maybe more. As for the problem with the carriage returns in notepad, I check all bytes for a 10 if there was one, I wrote a 13 before it. Thus keeping the original file structure. Which btw Internet explorer doesn't do when saving a txt file.
for (int i = startPos;i<512;i++) { if (buff == 0) break; char temp[1]; temp[0] = buff; f.Write(temp,1); chrecv +=1; }
here is what it should be
for (int i = startPos;i<500;i++) { //if (buff == 0) break; char temp[1]; temp[0] = buff; f.Write(temp,1); chrecv +=1; }
simple enough, but an annoying error. Just downloaded a 7mb file perfectly. I have also integrated support for proxys (I hope) I have to test it tommorow.
I still need to include code to deal with a moved file, or a 100 continued status code. and also chunked data. When I have done that, I will maybe implement a html viewer into it, and maybe more. As for the problem with the carriage returns in notepad, I check all bytes for a 10 if there was one, I wrote a 13 before it. Thus keeping the original file structure. Which btw Internet explorer doesn't do when saving a txt file.
www.stickskate.com -> check it out, some gnarly stick skating movies
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement