Pois é, faz tempo que não posto nada por aqui… Mas estou voltando e vou voltar a escrever sobre algumas coisas que ando desenvolvendo nas horas vagas.
OrionSocket é uma biblioteca (ainda bem simples e em desenvolvimento) em alto nível para manipulação de sockets em C em Linux/*BSDs. O foco dela é mais agilizar o desenvolvimento de aplicações cliente/servidor para os protocolos HTTP, FTP, etc. Ainda há muita coisa a ser feita, portanto vou postando aqui as funcionalidades que forem sendo adicionadas com o tempo.
O projeto é opensource e também está hospedado no google code no link http://orionsocket.googlecode.com/.
Depois de baixar, o modo de instalação é o velho conhecido dos usuários linux/BSDs:
$ tar zxvf orionsocket-1.0.4.tar.gz
$ cd orionsocket-1.0.4
$ ./configure –prefix=/diretorio/para/instalar
$ make
$ sudo make install
Agora vamos ver como utilizar a biblioteca.
Exemplo 1:
/**
* Author: Tiago Natel de Moura
* Date: 14/08/2010
*/
#include <stdio.h>
#include <stdlib.h>
// Library OrionSocket
#include <orion/socket/http.h>
int main(int argc, char** argv)
{
orion_httpRequest *req = NULL;
char *response = NULL;
int code;
const char* domain = "universemachine.wordpress.com";
// Inicializa a estrutura orion_httpRequest
orion_initHttpRequest(&req);
// Ajusta o host e a porta alvo
orion_setHttpRequestHost(req, domain, 80);
// Ajusta o PATH da requisição, por default é /
orion_setHttpRequestPath(req, "/");
// Ajusta um Header qualquer, no caso o User-Agent
orion_setHttpRequestHeader(req, "User-Agent", "Anakin SkyWalker");
// Faz a requisição HTTP e retorna a resposta do servidor na variavel response
code = orion_httpRequestPerform(req, &response);
if (code == ORIONSOCKET_OK)
{
printf("%s\n", response);
free(response);
}
// Desaloca a memória da estrutura
orion_cleanupHttpRequest(req);
return 0;
}
Para compilar utilize:
$ gcc -Wall exemplo1.c -o exemplo1 -lorionsocket
O exemplo acima está bem documentado e mostra como é simples e rápido fazer um cliente http. Mas a função orion_httpRequestPerform nem sempre é uma boa opção, pois ela faz a requisição no servidor e armazena toda a resposta na variavel passada como buffer para ela. Para fazer isso, ela lê todo o socket e só depois traz a resposta. Em alguns casos, por exemplo quando a resposta for muito grande ou em servidores que não retornam todo o buffer de uma vez (google.com), sua aplicação pode ficar vários segundos à espera da resposta sem ter feedback do que está ocorrendo.
Pra resolver esse problema, existe uma outra função muito útil chamada orion_httpGet que utiliza de um callback, deixando assim o desenvolvedor manipular o buffer de resposta.
Abaixo um exemplo utiiizando orion_httpGet().
Exemplo 2:
#include <stdio.h>
#include <orion/socket/http.h>
void myCallBack(char* buffer, unsigned int count)
{
printf("%s\n", buffer);
}
int main(int argc, char** argv)
{
orion_httpRequest* req = NULL;
orion_initHttpRequest(&req);
orion_setHttpRequestHost(req, "universemachine.wordpress.com", 80);
// Realiza a requisição no host especificado em req e envia o buffer
// para a função myCallBack
int code = orion_httpGet(req, myCallBack, 100);
if (code == ORIONSOCKET_OK)
printf("\n[+] requisição realizada com sucesso.\n");
else
printf("\n[-] erro ao fazer requisição...\ncodigo de erro=%d\n", code);
orion_cleanupHttpRequest(req);
return 0;
}
$ gcc -Wall -o exemplo2 exemplo2.c -lorionsocket
A assinatura da função orion_httpGet é:
_uint8 orion_httpGet(orion_httpRequest* req, void (* callback)(char*,_uint32), _uint32 count)
Em breve disponibilizarei uma documentação online (doxygen) do projeto.
Se voce achar realmente necessário, voce pode baixar o nível e trabalhar diretamente com o socket da seguinte forma:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <orion/socket/socket.h>
#define LEN 1024
int main(int argc, char** argv)
{
if (argc < 2)
{
fprintf(stderr, "[ERROR] Usage: %s <host> <port>\n", argv[0]);
return 0;
}
char temp[LEN];
int n;
// Inicializa um socket TCP/IP e conecta no alvo
// Retorna o socket criado e conectado
int sockfd = orion_tcpConnect(argv[1], atoi(argv[2]));
bzero(temp, LEN);
if (send(sockfd, "GET / HTTP/1.1\nHost: xxx\n\n", 26, 0) < 0)
{
fprintf(stderr, "[-] Erro ao enviar os dados.\n");
close(sockfd);
return 1;
}
while ((n = read(sockfd, temp, LEN-1)) > 0)
{
printf("%s\n", temp);
bzero(temp, LEN);
}
close(sockfd);
return 0;
}
$ gcc -Wall -o exemplo3 exemplo3.c -lorionsocket
É isso aí, os exemplos estão comentados. Conforme a API for ganhando forma eu vou postando aqui as formas de utilização.
[...] post anterior eu mostrei como receber a resposta numa string do tipo C. Mas é possivel também ter a resposta [...]