Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: [VC++] recv epäonnistuu

alottelijaa [06.04.2010 20:42:07]

#

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();
		 }

Metabolix [06.04.2010 20:49:06]

#

HTTP-protokollassa viimeisen otsikon jälkeen kuuluu tulla kaksi rivinvaihtoa. Lisäksi otsikko Connection: close ei olisi hassumpi.

alottelijaa [06.04.2010 20:57:28]

#

"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ä?

Metabolix [06.04.2010 21:07:10]

#

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);

alottelijaa [06.04.2010 21:10:49]

#

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.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta