Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Tiago Souza Ribeiro

Obter conteúdo de página html e de arquivo txt

Recommended Posts

Olá. Não conheço muitas funções de C, no máximo printf, getch, scanf e system, kkk, a sintaxe já conheço, é parecida com PHP. Então, eu estou ajudando um cara aqui no servidor de um jogo, e preciso fazer um updater pra ele, pelo prompt de comando mesmo. Só que preciso saber como fazer isso:

 

> Obter o conteúdo de uma página HTML ou arquivo TXT de um servidor web

> Obter o conteúdo de um arquivo TXT local, no mesmo diretório do programa

> Baixar arquivos compactados do servidor web, e extrair na mesma pasta do programa, substituindo outros arquivos com mesmo nome automaticamente, mostrando % de download.

 

Caso ajude, o que pretendo é comparar o conteúdo do arquivo txt local com o do servidor web, e se forem diferentes, baixar um arquivo e extraí-lo. Vou tentar representar +/-:

 

int instalada, atualizada;
instalada = conteudo do arquivo .txt local;
atualizada = conteudo do arquivo remoto;
if(instalada != remoto){
printf("Uma atualiza\x87\xC6o est\xA0 dispon\xA1vel! Atualize seu client antes de jogar.");
}
else {
system("start client.exe ur;name=test;ip=xxx.xxx.xxx.xxx;port=xxxx");
}
while(instalada != remoto) {
baixar = instalada+1;
printf("Baixando atualiza\x87\xC6 de vers\xC6 %d.", baixar);
obtem arquivo compactado do endereço ("http://exemplo/%d.zip", baixar);
extrai arquivo na mesma pasta onde o programa esta compactado substituindo arquivos;
instalada++;
}
else {
system("start client.exe ur;name=test;ip=xxx.xxx.xxx.xxx;port=xxxx");
}

 

Dados adicionais:

 

- Não tenho certeza alí da função system(), naquela parte lá eu preciso executar o comando start client.exe ur;name=test;ip=xxx.xxx.xxx.xxx;port=xxxx no prompt de comando.

- Pode haver de o client está muito desatualizado, e nesse caso, ele vai atualizando versão por versão, até chegar na mais recente.

- Ah, não sei se é possível usar else em while, mas o que pretendi alí, é que quando o client estivesse na versão mais atualizada, automaticamente abrisse o jogo.

- Alí na url de download, usei .zip, mas pode ser qualquer formato compactado que C consiga manipular como desejo (extrair e substituir)

 

Aguardo uma ajudinha, vai ser muito útil *-------*

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tiago Souza Ribeiro,

 

Realmente em C não há a instrução while-else.

 

Para o updater, cria uma rede cliente-servidor e cada vez que o executa o jogo, conecta no servidor e verifica as versões dos arquivos/atualizações.

Conecte com o servidor através dos sockets. Lá no servidor fica rodando um programinha que responde aos clientes(jogo).

Espero que tenha entendido minha ideia.

 

Para compactação/descompactação sugiro a biblioteca zlib que é opensource.

 

Ainda não implementei nada com sockets, mas faz tempo que tenho vontade de fazê-lo.

Boa sorte no projeto!!

 

Espero ter ajudado, FLW! :grin:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tiago Souza Ribeiro,

 

Realmente em C não há a instrução while-else.

 

Para o updater, cria uma rede cliente-servidor e cada vez que o executa o jogo, conecta no servidor e verifica as versões dos arquivos/atualizações.

Conecte com o servidor através dos sockets. Lá no servidor fica rodando um programinha que responde aos clientes(jogo).

Espero que tenha entendido minha ideia.

 

Para compactação/descompactação sugiro a biblioteca zlib que é opensource.

 

Ainda não implementei nada com sockets, mas faz tempo que tenho vontade de fazê-lo.

Boa sorte no projeto!!

 

Espero ter ajudado, FLW! :grin:

 

Olá, obrigado por seu retorno, é de grande ajuda. Pesquisando aqui, vi que há sockets para Windows e para Linux. No meu caso, o cliente é Windows, mas o servidor é Linux. Vou ter que criar aplicações diferentes em cada um dos lados?

Ah, alí no while, como não há else, funcionaria se eu fizesse assim: ?

 

while(instalada != remoto) {
       baixar = instalada+1;
       printf("Baixando atualiza\x87\xC6 de vers\xC6 %d.", baixar);
       obtem arquivo compactado do endereço ("http://exemplo/%d.zip", baixar);
       extrai arquivo na mesma pasta onde o programa esta compactado substituindo arquivos;
       instalada++;
if(instalada == remoto){
	system("start client.exe ur;name=test;ip=xxx.xxx.xxx.xxx;port=xxxx");
}
}

 

--- Edit:

Pesquisando mais um pouco aqui, vi que pra esse projeto ae vou precisar mecher com Threads, fork...

Tô querendo algo o mais simples possível.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Pesquisando aqui, vi que há sockets para Windows e para Linux. No meu caso, o cliente é Windows, mas o servidor é Linux. Vou ter que criar aplicações diferentes em cada um dos lados?

 

Você vai ter que criar aplicações diferentes usando, em uma, a API do windows e, em outra, a API do linux, ou então usar algo como o Cygwin para rodar código do linux no windows (mais recomendado que usar o wine para rodar executáveis do windows no linux, pois é muito lento).

 

Existem bibliotecas que universalizam isso em C++, em C não conheço nenhuma, mas talvez existam.

 

 

Pesquisando mais um pouco aqui, vi que pra esse projeto ae vou precisar mecher com Threads, fork...

Tô querendo algo o mais simples possível.

 

Você pode fazer um listener no linux que cuida de um client por vez, mas isso não vai aguentar mais que, digamos, algumas centenas/milhares de requests sem ter delay, mais que isso você teria que usar threads mesmo.

 

 

Abraços :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você vai ter que criar aplicações diferentes usando, em uma, a API do windows e, em outra, a API do linux, ou então usar algo como o Cygwin para rodar código do linux no windows (mais recomendado que usar o wine para rodar executáveis do windows no linux, pois é muito lento).

 

Existem bibliotecas que universalizam isso em C++, em C não conheço nenhuma, mas talvez existam.

 

 

 

 

Você pode fazer um listener no linux que cuida de um client por vez, mas isso não vai aguentar mais que, digamos, algumas centenas/milhares de requests sem ter delay, mais que isso você teria que usar threads mesmo.

 

 

Abraços :D

 

O problema é que sou leigo em C, e não tenho tempo para estudar isso de sockets. Estava precisando de uma solução mais simples...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ah, pera, você só vai baixar arquivos?

 

Vai de cURL, é a melhor biblioteca de networking para C, use a curl_easy e faça downloads http...

 

http://curl.haxx.se

 

OBS: você quer usar a libcurl, não o curl em si, o curl é um executável que funciona em cima da libcurl.

 

 

Abraços :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ah, pera, você só vai baixar arquivos?

 

Vai de cURL, é a melhor biblioteca de networking para C, use a curl_easy e faça downloads http...

 

http://curl.haxx.se

 

OBS: você quer usar a libcurl, não o curl em si, o curl é um executável que funciona em cima da libcurl.

 

 

Abraços :D

 

Então essa parte do download tá certo, mas como eu faria para mostrar a % do arquivo sendo baixado?

E outra parte mais importante ainda, é comparar os arquivos .txt local e remoto. Alguma ideia de como eu poderia ler o conteúdo de um arquivo local, algo como fopen, fread do PHP, e para ler o arquivo remoto por HTTP?

 

Vlw pelo retorno :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Para mostrar a % do arquivo sendo baixado:

 

int progress_func(void* ptr, double TotalToDownload, double NowDownloaded, 
                   double TotalToUpload, double NowUploaded)
{
   // how wide you want the progress meter to be
   int totaldotz=40;
   double fractiondownloaded = NowDownloaded / TotalToDownload;
   // part of the progressmeter that's already "full"
   int dotz = round(fractiondownloaded * totaldotz);

   // create the "meter"
   int ii=0;
   printf("%3.0f%% [",fractiondownloaded*100);
   // part  that's full already
   for ( ; ii < dotz;ii++) {
       printf("=");
   }
   // remaining part (spaces)
   for ( ; ii < totaldotz;ii++) {
       printf(" ");
   }
   // and back to line begin - do not forget the fflush to avoid output buffering problems!
   printf("]\r");
   fflush(stdout);
}

Fonte: http://stackoverflow.com/questions/1637587/c-libcurl-console-progress-bar

 

Isso é em console, se estiver usando GUI, aplique a ela. Por exemplo, os exemplos do cURL mostram com o GTK:

 

http://curl.haxx.se/libcurl/c/curlgtk.html

 

 

---

 

 

Para ler o conteúdo do arquivo, a API do PHP é baseada na da C, então elas são bem parecidas, é aquela baseada em FILE * e fopen(), procure por "C file i/o" no google e veja alguns tutoriais =)

 

 

Abraços :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Para mostrar a % do arquivo sendo baixado:

 

int progress_func(void* ptr, double TotalToDownload, double NowDownloaded, 
                   double TotalToUpload, double NowUploaded)
{
   // how wide you want the progress meter to be
   int totaldotz=40;
   double fractiondownloaded = NowDownloaded / TotalToDownload;
   // part of the progressmeter that's already "full"
   int dotz = round(fractiondownloaded * totaldotz);

   // create the "meter"
   int ii=0;
   printf("%3.0f%% [",fractiondownloaded*100);
   // part  that's full already
   for ( ; ii < dotz;ii++) {
       printf("=");
   }
   // remaining part (spaces)
   for ( ; ii < totaldotz;ii++) {
       printf(" ");
   }
   // and back to line begin - do not forget the fflush to avoid output buffering problems!
   printf("]\r");
   fflush(stdout);
}

Fonte: http://stackoverflow...le-progress-bar

 

Isso é em console, se estiver usando GUI, aplique a ela. Por exemplo, os exemplos do cURL mostram com o GTK:

 

http://curl.haxx.se/.../c/curlgtk.html

 

 

---

 

 

Para ler o conteúdo do arquivo, a API do PHP é baseada na da C, então elas são bem parecidas, é aquela baseada em FILE * e fopen(), procure por "C file i/o" no google e veja alguns tutoriais =)

 

 

Abraços :D

 

O fopen só funciona com arquivos locais, ou remotos também, por HTTP?

Compartilhar este post


Link para o post
Compartilhar em outros sites
O fopen só funciona com arquivos locais, ou remotos também, por HTTP?

 

Não em sistemas normais. fopen() só abre arquivos locais, você tem que os baixar primeiro. Afinal, para abrir arquivos remotos com fopen() no php, ele baixa o arquivo primeiro, é só mais uma camada de abstração. C não tem essas camadas.

 

 

 

Abraços :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não em sistemas normais. fopen() só abre arquivos locais, você tem que os baixar primeiro. Afinal, para abrir arquivos remotos com fopen() no php, ele baixa o arquivo primeiro, é só mais uma camada de abstração. C não tem essas camadas.

 

 

 

Abraços :D

 

Ah, maldito C, só tem complicação :@

Acho que vou baixar com wget (for windows) mesmo, tanto o arquivo txt quanto o zip.

Ah, poderia me explicar ou indicar um tutorial de como usar o zlib pra descompactar arquivos zip? Estou procurando há horas e não acho :(

Compartilhar este post


Link para o post
Compartilhar em outros sites
Ah, maldito C, só tem complicação :@

 

Noooo, ela só não deixa você ficar sem saber o que acontece.

 

 

Acho que vou baixar com wget (for windows) mesmo, tanto o arquivo txt quanto o zip.

 

Chamar um executável? Que lixo. Cara, é muito fácil baixar um arquivo com o cURL. Pegue qualquer outra LIB, até a nativa do windows, muito mais complexo de mexer.

 

Por exemplo, vou por a implementação que fiz aqui (em C++ e sem progress bar), se quiser olhar... tem muito tempo que fiz, mas estava funcional, se não estou enganado. Eu usei só a lib da C (excluindo o new e delete) para implementar isso, então você não deve ter muita dificuldade em ler o código.

 

Downloader.hpp

https://gist.github.com/3008877

 

Downloader.cpp

https://gist.github.com/3008887

 

Abraços :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

muito mais complexo de mexer.

 

Isso mesmo que eu quero evitar '-'

Quero o mais simples possível, funcionando é o que importa ^^

 

Ao menos vai ser melhor que baixar manualmente as atualizações do jogo, seja lá como o programa funcionar, será útil para os jogadores lá.

Vou ver melhor esse código seu ae, não entendi quase nada dele, kkk, muito menos como se usa, e talvez eu troque o wget por ele...

O problema principal agora é a zlib, não achei nada sobre como usá-la, não faço ideia de como dar include nela no meu projeto...

Compartilhar este post


Link para o post
Compartilhar em outros sites
Isso mesmo que eu quero evitar '-'

Quero o mais simples possível, funcionando é o que importa ^^

 

É, o complexo é a API do windows, não sei se entendeu.

 

 

Ao menos vai ser melhor que baixar manualmente as atualizações do jogo, seja lá como o programa funcionar, será útil para os jogadores lá.

Vou ver melhor esse código seu ae, não entendi quase nada dele, kkk, muito menos como se usa, e talvez eu troque o wget por ele...

 

Um exemplo de como usar:

 

#include "Downloader.hpp"
#include <cstdio>

using namespace roojo; // Feio, mas só para ficar simples.
using namespace roojo::simplifier; // Feio, mas só para ficar simples.
using namespace std; // MUITO feio, mas só para ficar simples.

int main()
{
   Downloader downloader;
   Downloader::downCode downloadStatus;

   downloadStatus = downloader.download("<Link de download>", "<nome com que quer salvar o arquivo>");

   if(downloadStatus != Downloader::DOWNE_OK)
       printf("Error in the download!");

   return 0;
}

 

Lembre que tem que salvar como um arquivo de C++, não C. Você teria que reescrever o código em C para usar.

 

O problema principal agora é a zlib, não achei nada sobre como usá-la, não faço ideia de como dar include nela no meu projeto...

 

Ah, esqueci de responder isso ontem...

 

FAQ: http://zlib.net/zlib_faq.html

COMO USAR: http://zlib.net/zlib_how.html

MANUAL: http://zlib.net/manual.html

 

 

 

Abraços :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.