Yritän hakea winsockin avulla tiedostoa HTTP serveriltä. Jostain syystä kuitenkin recv epäonnistuu jokainen kerta enkä tiedä mikä on syynä. Keksiikö kukaan mikä tässä mättää :).
EDIT: siis recv palauttaa -1 jolloin Failed: viesti näytetään. ja jos jotain ihmetyttää Client << wsagetlasterror() niin halusin vain nähdä meneekö tiedostoon mitään. Ei :O
private: System::Void onClickUpdate(System::Object^ sender, System::EventArgs^ e) { bool err = 0; //lopetan funktion tällä.. this->textBox1->Text = L"Connecting to update server"; Application::DoEvents(); while (err == false) { WSADATA wsadata; if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0) { this->textBox1->Text = L"Failed: Could not initialize winsock"; err = true; } SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { this->textBox1->Text = L"Failed: Socket creation failed"; err = true; } struct hostent *host; if ( (host = gethostbyname("asd.serveri.org")) == NULL) { this->textBox1->Text = L"Failed: Failed to resolve hostname"; err = true; } SOCKADDR_IN sockaddr; sockaddr.sin_port = htons(80); sockaddr.sin_family = AF_INET; sockaddr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *) *host->h_addr_list)); //host:n ip käsittääkseni if (connect(sock, (const SOCKADDR*)(&sockaddr),sizeof(sockaddr)) != 0) { this->textBox1->Text = L"Failed: Couldnt connect to server"; err = true; } char* freq = "GET /updates/current.swf HTTP/1.0\r\nUser-Agent: AE Updater\r\nAccept: */ *\r\nHost: asd.serveri.org"; //get rivillä tarkoituksella väli / * kohdalla koska koodi värjäytyy väärin muuten const char* fileRequest = freq; char *buffer = NULL; int result = 0; std::ofstream Client("uusi.swf", std::ios::out); this->textBox1->Text = L"Succesfully connected to the server"; Application::DoEvents(); send(sock, fileRequest, strlen(fileRequest), 0); this->textBox1->Text = L"Loading client: please be patient"; Application::DoEvents(); do { result = recv(sock, buffer, 2048, MSG_WAITALL); //waitall ei vaikuta ongelmaan Application::DoEvents(); if (result == 0) { Client.close(); this->textBox1->Text = L"Checking if an update is needed..."; Application::DoEvents(); this->textBox1->Text = L"Update completed succesfully"; shutdown(sock, SD_SEND); closesocket(sock); Application::DoEvents(); err = true; } else if (result < 0) { Client << WSAGetLastError(); this->textBox1->Text = L"Failed: Download failed, please restart updater"; Application::DoEvents(); shutdown(sock, SD_SEND); closesocket(sock); err = true; } else { this->textBox1->Text = L"Perskuta tulee dataa!"; Application::DoEvents(); Client << buffer; buffer = NULL; } } while (result > 0); } //pakko olla ettei while jatku se on muutenkin vaan errorien havaittemiseen //while loppuu WSACleanup(); //jos jotain menee pieleen Application::DoEvents(); }
HTTP-protokollassa viimeisen otsikon jälkeen kuuluu tulla kaksi rivinvaihtoa. Lisäksi otsikko Connection: close
ei olisi hassumpi.
"GET /updates/current.swf HTTP/1.0\r\nUser-Agent: AE Updater\r\nAccept: */*\r\nHost: asd.server.org\r\nConnection: close\r\n\r\n"
tuollaisen lähetin ja lopputulos on sama. Apachen access-loki näyttää että pyyntö tuli: "GET /updates/current.swf HTTP/1.0" 200 190025. Eikös 200 ole OK ja tiedoston pitäisi lähteä?
Pitäisihän sieltä joka tapaukessa tulla dataa, nimittäin vastauksen HTTP-otsikot:
HTTP/1.0 404 Not Found Content-type: text/html; charset=UTF-8 Content-Length: 16 Connection: close Date: Tue, 06 Apr 2010 18:03:15 GMT Server: lighttpd/1.4.26 404 - Not Found!
Onneksesi huomasin kuitenkin virheen: et ole varannut puskurille tilaa. Puskurina pitäisi käyttää taulukkoa eikä tyhjää osoitinta.
// Valmis taulukko, koko sizeof-operaattorilla: char buffer[2048]; recv(sock, buffer, sizeof(buffer), 0); // Dynaamisesti sizeof-operaattori ei toimi: char* buffer = new char[2048]; recv(sock, buffer, 2048, 0);
Nyt toimii, kiitos Metabolix!
Aikaisemmin visual C++ heitti jonkun ihan oudon virheen ja sain sen poistumaan vain vaihtamalla char a[]:n pointeriksi, mutta näemmä ongelma on hävinnyt.
Aihe on jo aika vanha, joten et voi enää vastata siihen.