Tiago Natel de Moura

OrionSocket – Biblioteca básica de sockets em C

Em C, orionsocket, sockets, agosto 15, 2010 às 12:39 am

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/.

Download

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.

  1. [...] post anterior eu mostrei como receber a resposta numa string do tipo C. Mas é possivel também ter a resposta [...]

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Sair / Alterar )

Imagem do Twitter

You are commenting using your Twitter account. Sair / Alterar )

Foto do Facebook

You are commenting using your Facebook account. Sair / Alterar )

Connecting to %s

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.