Народ,я решил попробывать свои силы и сделать качалку фаилов )) , создал сокет, отправляю запрос http серверу на получение фаила,теперь вопрос е подскажите,где можно почитать про получение данных из сокета и сохрание на диске,как убрать из сокета ответ http сервера? Пишу на С++ Зарание благодарен ЗЫ ногами сильно не бить,я только учусь ))
.data file db "C:\test.exe",0 url db "your_host/file",0 .code invoke URLDownloadToFile, NULL,ADDR url ,ADDR file ,0,NULL в wininet.dll функция http://www.wasm.ru/article.php?article=socketvssocket З.Ы.:на каком языке пишешь?
2 GoreMaster Он укзал что пишет на С++. Твой пример хорошь, но на нем него нельзя нацепить прогрессбар 2 [NiGHT]DarkAngel Ты из соката через recv читай сначала данные во временный буфер. КОгда уже пройдут все HTTP заголовки. то потом начинай читать и сразу писать в файл.
http://forum.web-hack.ru/index.php?showtopic=6328 Тебе еще потребуются знание http-протокола. Юзай гугл. Вкратце: сначала посылаешь GET-запрос, затем получаешь в цикле через recv получаешь инфу. Что-то вроде этого: Code: char buf_in[10]; int x; char page_text[50000]; //тут будет храниться все, что получаешь x=recv(sock,buf_in,sizeof(buf_in)-1,0); while(x>0) { buf_in[x]=0; lstrcat(page_text,buf_in); // printf(buf_in); x=recv(sock,buf_in,sizeof(buf_in)-1,0); } Ну и еще пример функции. Я писал ее, чисто чтобы получать код страницы, а не файла. Но суть-то одна и таже. Ты и файл ей получишь. Code: char* GETRequest(char* server,char* page) { WSADATA sock_info; int err=WSAStartup(MAKEWORD(2,0),&sock_info); if(err==SOCKET_ERROR) { printf("WSAStartup error"); return 0; } int sock; struct sockaddr_in sa; struct hostent* h; char page_text[50000]; char buf_in[10]; char buf_out[500]; int x; sa.sin_family=AF_INET; sa.sin_port=htons(80); h=gethostbyname(server); memcpy(&sa.sin_addr,h->h_addr_list[0],h->h_length); sock=socket(AF_INET,SOCK_STREAM,0); if(connect(sock,(sockaddr*)&sa,sizeof(sa))<0) { printf("connect() error"); return 0; } lstrcpy(buf_out,"GET "); //Составляем GET-запрос lstrcat(buf_out,page); lstrcat(buf_out," HTTP/1.0\r\n"); send(sock,buf_out,lstrlen(buf_out),0); lstrcpy(buf_out,"Host: izobilnik.ru\r\n"); send(sock,buf_out,lstrlen(buf_out),0); lstrcpy(buf_out,"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, */*\r\n"); send(sock,buf_out,lstrlen(buf_out),0); lstrcpy(buf_out,"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)\r\n\r\n"); //заголовок User-Agent: send(sock,buf_out,lstrlen(buf_out),0); lstrcpy(page_text,""); x=recv(sock,buf_in,sizeof(buf_in)-1,0); while(x>0) { buf_in[x]=0; lstrcat(page_text,buf_in); // printf(buf_in); x=recv(sock,buf_in,sizeof(buf_in)-1,0); } closesocket(sock); return page_text; } пример использования: Code: char p[50000]; lstrcpy(file,GETRequest("izobilnik.ru","/yourfile.zip")); по идее в p, должен быть ответ от сервера, вместе с файлом. Если файл большой, то увеличь значение в 50000
Так я научился получать данные и псиать в фаил )) , подскажите плз еще немножко,как убрать из фаила ответ Http-сервера ?или где почитать )) Зарание благодарен
получение данных из сокета - recv() и recvfrom(), тебе нужна первая сохранение на диске - запиши в файл. например CreateFile(), WriteFile(), CloseHandle() убрать ответ сервера - обреж все до двух \r\n подряд и дальше сохраняй. как я понимаю ты сначала записываешь в файл все, что вернул сервер. если да то пошли с нами долбаться и гонять по вене. на*** сохранять в файл ответ сервера? получаешь ответ, пока не встретятся \r\n два раза. затем читаешь в буффер скажем по 5кб данных и сохраняешь в файл. если надо эстетичнее - находи Content-Length: X и считывай X после переносов. если ещё эстетичнее - InternetOpen(), HttpOpenRequest(), HttpSendRequest() и так далее. например из illusion Code: DWORD Download( LPSTR server, LPSTR path, LPSTR local ) { HINTERNET hInternet = _InternetOpen( TEXT("Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.5a) Gecko/20030728 Mozilla Firebird/0.6.1"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ); if (!hInternet) return 5; HINTERNET hConnect = _InternetConnect( hInternet, TEXT( server ), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (LPDWORD)1u ); if (!hConnect) return 6; HINTERNET hRequest = _HttpOpenRequest( hConnect, TEXT( "GET" ), TEXT( path ), NULL, NULL, 0, INTERNET_FLAG_KEEP_CONNECTION, (LPDWORD)1 ); if (!hRequest) return 7; BOOL bSend = _HttpSendRequest( hRequest, NULL, NULL, NULL, NULL ); if (!bSend) return 8; /* delete old file */ _DeleteFile( local ); /* create new */ HANDLE hFile = _CreateFile( local, GENERIC_WRITE, NULL, NULL, CREATE_NEW, NULL, NULL ); if (hFile == INVALID_HANDLE_VALUE) return 9; DWORD dwBytesRead, dwBytesWrite; BYTE szData[1024]; BYTE ret = 0; for (;;) { if (!Opt_HTTP_Download.started) { ret = 1; break; } BOOL bRead = _InternetReadFile( hRequest, szData, sizeof( szData ) - 1, &dwBytesRead ); Opt_HTTP_Download.filesize += 1024; //dwBytesRead; if (!bRead || !dwBytesRead) break; szData[dwBytesRead] = 0; if (!_WriteFile( hFile, szData, dwBytesRead, &dwBytesWrite, NULL ) || !dwBytesWrite) break; } _CloseHandle( hFile ); _InternetCloseHandle( hRequest ); _InternetCloseHandle( hConnect ); _InternetCloseHandle( hInternet ); if (ret) return 255; else return 1; } _funcname заменяй на funcname всякие if (!Opt_HTTP_Download.started) уберай je0n, пиздец ты друг накатал ***ни) может будет по байту запрос составлять и отсылать по байту? так нельзя? sprintf( request, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", path, host ); send( s, request, strlen( request ), 0 ); *** ты из файла, в котором встречаются нулевые байты, запишешь таким образом данные угу, а потом return page_text ... да, все-таки некоторым больше подойдет делфи ну а тут вообще без комментариев Гениальный совет кодера. Не даром у тебя написано "asm+delphi". Нахер спрашивается читать сначала в буффер, выделяя -неизвестное- кол-во памяти, а потом в файл, если можно сразу пропустить заголовки и в файл? PS кез спит, сейчас разбужу, забыла какая есть ф-ия ещё API там... а. всмысле это нерд пишет) приветик)
Если у тебя с алгоритмикой все в порядке, должен догадаться (RFC почитать что-ли, ну или хз), что данные отделяются от заголовка последовательностью \r\n\r\n Ищи эти 4 байта в ответе сервера. ЗЫ. это если протокол 1.0. У протокола 1.1 там свои выкрутасы еще есть. Ну.. для протокола хттп 1.0 достаточно просто сохранять тупо всё, пока сокет не закроют на сервере. Для протокола 1.1 - там передается отдельно длина запроса, и после передачи всего тела сокет не закрывается, так что если этого не учесть, твоя прога повиснет, когда получит все данные, и отвиснет только после разрыва соединения по тайм-ауту
2 Kez млин. конечно нужен временный буфер куда читать. я просто навренео не правильно выразился. я имел в виду троковую переменну. в которую читать данные и искать конец Http заголовка.
Так вроде чето получилось написать,хтмл странички принимаю без проблем,а вот с остальным rar, exe и тд. как то не важно,куда то теряются данные при передачи (( Если не трдуно посмотрите пожалйуста исходник и моно носом ткнуть что и где неправильно)) Ногами сильно не бить , я только учусь и в этой проге куча всяких недостатков и багов,но все ранво зарание всем спасибо за все ) Code: //--------------------------------------------------------------------------- #include <vcl.h> #include <iostream.h> #include <conio.h> #include <winsock2.h> #include <stdlib.h> #include <stdio.h> #pragma hdrstop //--------------------------------------------------------------------------- class my_socket { public: SOCKET client; my_socket(); ~my_socket(); int error() {cout << "!!! Owu6ka !!!" << WSAGetLastError() << endl; return 1;} int sends(char *byf,SOCKET client); }; my_socket::my_socket() { WSAData w; int error=WSAStartup (0x0202, &w); if (error) { cout << "Neizvestna9 owubka :( " <<endl; } if (w.wVersion != 0x0202) { // íå òà âåðñèÿ ñîêåòîâ! WSACleanup (); // âûãðóæàåì ws2_32.dll } cout << "Rabotaet konstructor" << endl; } my_socket::~my_socket() { WSACleanup(); cout << "Rabotaet destructor " << endl; } int my_socket::sends(char *buff, SOCKET client) { int rVal=0; rVal = send(client,buff,strlen(buff),0); if(rVal == SOCKET_ERROR) { cout <<"Failed send()"<<endl; return 1; } else {cout << " Yspewno peredalos' " << endl;} return 0; } #pragma argsused int main(int argc, char* argv[]) { cout << "Na4alo rabotu programmu" << endl; my_socket my; SOCKET s; sockaddr_in target; s = socket (AF_INET, SOCK_STREAM, 0); // Ñîçäà¸ì ñîêåò target.sin_family = AF_INET; // ñåìåñòâî àäðåñîâ - Èíòåðíåò target.sin_port = htons (80); // ïîðò ñåðâåðà target.sin_addr.s_addr = inet_addr ("127.0.0.1"); //target.sin_addr.s_addr = inet_addr ("87.224.128.10"); // IP-àäðåñ ñåðâåðà int rVal=0; rVal=connect(s,(LPSOCKADDR)&target, sizeof(target)); if(rVal==SOCKET_ERROR) { cout << "Failed connection" << endl; return 1; } else {cout << " Socket yspewno soedenils9" << endl;} my.sends("GET http://127.0.0.1/files/my.txt HTTP/1.0\r\n\r\n",s); my.sends("User-Agent: myDownload 0.1\r\n\r\n",s); my.sends("Accept: */*\r\n\r\n",s); my.sends("Host: 127.0.0.1 \r\n\r\n",s); //my.sends("Connection: close\r\n\r\n",s); char buf_in[8]; int x; char page_text[190000]; //òóò áóäåò õðàíèòüñÿ âñå, ÷òî ïîëó÷àåøü FILE *tele; if ((tele = fopen("my.txt","w+b")) == NULL) { cout << " Open file error " <<endl; getch(); return -1; } x=recv(s,buf_in,sizeof(buf_in)-1,0); while(x>0) { buf_in[x]=0; lstrcat(page_text,buf_in); //cout << buf_in; //getch(); x=recv(s,buf_in,sizeof(buf_in)-1,0); } cout << endl << "strlen(page_text) = " << strlen(page_text) << endl; int i; for (i=0;i<strlen(page_text);i++) { if ((page_text[i]=='\r') && (page_text[i+1]=='\n') && (page_text[i+2]=='\r')&& (page_text[i+3]=='\n')) { cout << "Est' taka9 stroka i = " << i << endl; break; } } int p,b,q; p=i+4; q=(strlen(page_text)-p); char *stroka; cout << "p = " << p<< endl; cout << "strlen = " << q << endl; for (b=p;b<strlen(page_text);b++) { cout << "b= " <<b << endl; stroka=&(page_text[b]); fwrite(stroka,strlen(stroka),1,tele); break; } closesocket(s); my.~my_socket(); getch(); return 0; } //---------------------------------------------------------------------------
Б**** сколько ещё раз написать тебе что lstrcat - присоединяет СТРОКУ. Строка заканчивается нулевым символом. А у тебя содержимое рар или ехе может иметь что угодно, в том числе и нули. И ещё, мне кажется что тебе рановато использовать КЛАССЫ. Ещё и такие бессмысленные как в данном случае. Спрашивается - нахера они тебе тут нужны?
Sorry 2 all... Вот накатал скачивание при помощи класса CInternetFile библиотеки MFC. Code: void DownloadFile(LPCSTR pstrURL,LPCSTR lpszFileName) { CInternetSession inetSession; CInternetFile *inetFile = (CInternetFile *) inetSession.OpenURL(pstrURL, 1, INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE); CFile file(lpszFileName,CFile::modeCreate | CFile::modeWrite | CFile::typeBinary); char buf[8192]; DWORD dwBytesRead; while (dwBytesRead=inetFile->Read(buf, sizeof(buf))) file.Write(buf, dwBytesRead); inetFile->Close(); delete inetFile; inetSession.Close(); }
NetMan, может проще взять Download Master ? [NiGHT]DarkAngel, не поддавайся на провокации. еб*аш Свой довнлоадер пока не заработает. если не получается по другому, то нужно учится и на своих ошибках..
с начала не читал так что есди не попаду в тему то просто не обращайте внимания FILE *out; while(x=ecv(s,buf_in,sizeof(buf_in)-1,0)) { buf_in[x]=0; fwrite(buf_in,x,1,out); } че то типа того
Я не знаю даже. Может вам картинку с комиксом нарисовать надо или под музыку песню написать где рассказывается на китайском что strcat() прикрепляет строку к строке а не массив байт к массиву байт и что через MFC делать скачивание файла - все равно что через 3DS MAX рисовать точку на экране?
Блин, стоит только отойти, уже флейма разведут на Н страниц. Таких тем в инете полно! Исходников тоже! На крайняк если ТС ничего не найдет (вероятность менее 1%), то я потом выложу в паблик Antichat Web Tool, где скачивание страницы реализовано через чистые сокеты. В двух словах: Code: SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); SOCKADDR_IN sa = {0}; sa.sin_family = AF_INET; HOSTENT* phe = gethostbyname("google.ru"); *(DWORD*)&sa.sin_addr.s_addr = *(DWORD*)phe->h_addr_list[0]; sa.sin_port = htons(80); connect( s, &sa, sizeof(sa) ); const int bsize = 1024*1024; // 1 megabyte char *buffer = new char[bsize]; wsprintf( buffer, "GET http://google.ru/ HTTP/1.0\r\nHost: google.ru\r\n\r\n" ); send( s, buffer, strlen(buffer), 0 ); int bytes = 0, pos = 0; do { bytes = recv( s, buffer+pos, bsize-pos, 0 ); if( !(bytes>0) ) break; pos += bytes; buffer[pos] = 0; } while(1); closesocket( s ); char *body = strstr( buffer, "\r\n\r\n" ); body += 4; // strlen of \r\n\r\n // now buffer contains full response, body contains only response body delete buffer; Скачка файла через MFC - из пушки по воробьям Тема закрыта