Eli voisiko joku selittää kun olen noita enklannin kielisiä juttuja selaillut niin yksinkertaistetumman ohjeen, että miten voin katsoa, esim netistä jonkun tiedoston (.txt) sisällön C++. Kaikkia socketteja yms tarvitaan, mutta kun kaikissa paikoissa neuvotaan erillailla. Esim winapina ja socketeilla ja kaikkea, niin olisiko liikaa pyydetty sellainen tiivistetympi opas? Voisi olla ohjelmointiputkassa muutenkin hyödyllinen. :)
Se etten osaa, enkä ole löytänyt opasta. Yritän tehdä updateria. Joka katsoo netissä olevasta tekstitiedostosta päivityksen version ja vertaa sitä pelin sisäiseen tekstitiedostoon, että pitääkö päivittää ja sit päivity sohjelma etsii setup.exe tiedoston ja lataa sen.
URLDownloadToFilellä tiedoston lataus onnistuu helposti, jos haluat mennä naimisiin WinAPIn kanssa.
#include <windows.h> #include <stdio.h> int main(int argc, char *argv[]) { /* Ohjelma ottaa parametriksi URLin. */ if (argc != 2) { printf("käyttö: %s <url>\n", argv[0]); return 1; } /* Etsi URLDownloadToFile, ku se ei löydy MinGW:n kirjastoista :( */ WINAPI HRESULT (*URLDownloadToFile)(LPUNKNOWN pCaller, LPCTSTR szURL, LPCTSTR szFileName, DWORD dwReserved, LPVOID lpfnCB); URLDownloadToFile = (void *)GetProcAddress(LoadLibrary("urlmon.dll"), "URLDownloadToFileA"); if (!URLDownloadToFile) { fprintf(stderr, "urlmon.URLDownloadToFileA kadoksissa :o\n"); return 2; } /* Luo tiedostopolku väliaikaistiedostoon. */ char tmp_path[MAX_PATH], tmp_fn[MAX_PATH]; GetTempPath(sizeof(tmp_path), tmp_path); GetTempFileName(tmp_path, "get", 0, tmp_fn); /* Lataa. */ printf("ladataan \"%s\"\n", argv[1]); if (URLDownloadToFile(NULL, argv[1], tmp_fn, 0, NULL) != S_OK) { fprintf(stderr, "fail, ehkä \"%s\" on huono url\n", argv[1]); return 3; } /* Kirjoita ladatun tiedoston sisältö stdout-virtaan. */ FILE *file; if (!(file = fopen(tmp_fn, "rb"))) { fprintf(stderr, "tiedosto \"%s\" ei aukea\n", tmp_fn); return 4; } do { char buf[512]; fread(buf, 1, sizeof(buf), file); fwrite(buf, 1, sizeof(buf), stdout); } while (!feof(file)); fclose(file); /* Ole kiva ja poista väliaikaistiedosto. */ DeleteFile(tmp_fn); return 0; }
Onko jokin muukin mahdollisuus sitten kuin winapi?
mika132 kirjoitti:
Onko jokin muukin mahdollisuus sitten kuin winapi?
Voit tietysti tehdä käsin soketeilla, mutta se on huomattavasti työläämpi ja virhealttiimpi ratkaisu, joka ei myöskään porttaudu ihan nätisti. Socket-rajapinnoissa on eri käyttöjärjestelmien välillä pieniä eroja.
Kolmas vaihtoehto on käyttää jotain ulkopuolista kirjastoa, kuten libcurlia. Sillä tiedoston lataaminen muistiin onnistuu näin. Hyvinä puolina helppo käyttö ja porttautuvuus, mutta riippuvuus ulkoisista kirjastoista on joskus vitusta.
Kokeilepa syöttää hakuun sanat C++ tiedosto netistä. Saatat jopa löytää koodivinkin.
UrlDownloadToFile, UrlDownloadToCacheFile, libcurl, winsock taikka wininet.
Koita googletella noista jokin, kaikki oikeastaan aika helpohkoja, paitsi noista soketeista en tiedä kun en oo ikinä tutustunut.
SFML:ä onnistuu myös lataaminen. Alla pieni esimerkki aiheesta. Tässä käytetään http:ä yhdistämiseen vain sen takia, että kapsin palvelimelle ei saa otettua ftp-yhteyttä. ftp:ä tämä olisi toki miellyttävämpi tehdä.
#include <SFML/network.hpp> #include <iostream> #include <fstream> void Lataa_tiedosto(const std::string& isanta, const std::string& palvelimella, const std::string& levylla, unsigned int portti = 0) { sf::Http http; sf::Http::Request pyynto; unsigned int tiedoston_koko = 0; http.setHost(isanta, portti); pyynto.setUri(palvelimella); sf::Http::Response sivu = http.sendRequest(pyynto); tiedoston_koko = sivu.getBody().size(); if (tiedoston_koko > 0) { std::string tmp_tiedosto = sivu.getBody(); std::ofstream tiedosto(levylla.c_str(), std::ios::out | std::ios::binary); tiedosto.write(tmp_tiedosto.c_str(), tiedoston_koko); tiedosto.close(); } else { std::cout << "Osoitteeseen: " << isanta << palvelimella << " ei saada yhteyttä" << std::endl; } } int main(int kpl, char** argumentit) { std::string isanta = "isanta/"; std::string tiedosto = "kansio/jossa/ladattavaa.zip"; std::string paikallinen = "levylle.zip"; switch (kpl) { case 4: paikallinen = std::string(argumentit[3]); case 3: tiedosto = std::string(argumentit[2]); case 2: isanta = std::string(argumentit[1]); } Lataa_tiedosto(isanta, tiedosto, paikallinen, 80); return 0; }
Kääntyy gcc:ä komennolla g++ main.cpp -o ohjelma.exe -lsfml-network -lsfml-system
Aihe on jo aika vanha, joten et voi enää vastata siihen.