Socket Class - C++

Started by Dark_Side, 19 de April , 2007, 07:41:27 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Dark_Side

Hi,

Acabei de escrever uma classe bem simples para Sockets em C++ (Windows).

A classe pode trabalhar sob os protocolos UDP e TCP. Há as seguintes funções:

QuoteWinsock.Iniciar() -> inicia o uso do winsock;
Winsock.Terminar() -> finaliza o uso;

Socket.Criar(VALOR) = cria um socket. O parâmetro VALOR é um inteiro que pode ser 1 - TCP ou 2 - UDP;

Socket.Conectar(hostname,porta) -> se conecta a um computador remoto;

Socket.Aguardar(porta,num) -> aguarda um número "num" de conexões em uma porta "porta";

Socket.Aceitar(novo_socket) -> aceita uma conexão e a associa a uma nova classe de socket, se passado como NULL, a própria classe em uso é utilizada;

Socket.Enviar(dados) -> envia dados para um computador remoto;

Socket.Receber(tam) -> recebe um máximo "num" bytes e armazena os dados na variável "buffer" da classe.

Socket.HostRemoto() -> retorna o IP do computador remoto;

Socket.PortaRemota() -> retorna a porta utilizada no computador remoto;

Socket.Fechar() -> fecha o socket;

Bem, após uma breve explicação, vamos ao código:

#if !(defined _WINSOCK2_H || defined _WINSOCK_H)
#include <winsock2.h>
#endif

using namespace std;

string erro;
class WinSock{
     private:
                WSADATA wsa;
                BOOL    iniciado;
     public:
                void    Iniciar();
                void    Terminar();
 }WinSock;

class Socket
{
     private:
                SOCKET        sock;
                struct        sockaddr_in addr;
                struct        hostent * host;
                BOOL          criado;
                BOOL          UDP;
     public:
                void          Aceitar(Socket * novo_sock);
                void          Aguardar(DWORD porta, DWORD numero);
                void          Conectar(string hostname, DWORD porta);
                void          Criar(short tipo);
                DWORD         Enviar(string dados);
                void          Fechar();
                string        HostRemoto();
                DWORD         Receber(DWORD max);
                DWORD         PortaRemota();

                string        buffer;

            };

/////////////////////////////////////////////////////////////////////////////////////////
void WinSock::Iniciar()
{
     
     erro = "O Winsock ja foi inicializado!\n";
     if(iniciado == 1)
       throw erro;
       
     erro = "Erro ao incializar o Winsock.\n";
     
     if(WSAStartup(0x202,&wsa) == -1)
        throw erro;         
     
     iniciado = 1;                     
}
/////////////////////////////////////////////////////////////////////////////////////////


void WinSock::Terminar()
{
     erro = "Falha ao finalizar o uso do WinSock.\n";
     if(WSACleanup() == -1)
       throw erro;
       
     iniciado = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
 

void Socket::Criar(short tipo){
 
UDP = FALSE;

 erro = "O socket ja foi criado!\n";
if(criado == 1)
  throw erro;

           
short valores[2] = {SOCK_STREAM,SOCK_DGRAM};     
 
 erro = "Erro ao criar socket. O 'tipo' definido nao e' valido!\n";
if(tipo != 1 && tipo != 2)
  throw erro;
 
 
 erro = "Ocorreu um erro ao criar o socket.\n";
if((sock = socket(AF_INET,valores[tipo-1],0)) == -1)
   throw erro;

if(tipo == 2)
  UDP = TRUE;
 
criado = 1;

}
/////////////////////////////////////////////////////////////////////////////////////////

void Socket::Conectar(string hostname,DWORD porta)
{
     
     erro = "Erro ao resolver o host: "" + hostname + "".\n";
     if(!(host = gethostbyname(hostname.c_str())))
       throw erro;
       
        addr.sin_family = AF_INET;
        addr.sin_port   = htons(porta);
        addr.sin_addr   = *(struct in_addr*)host->h_addr;
       
       erro = "Erro ao se conectar ao host "" + hostname + "".\n";
        if(connect(sock,(struct sockaddr*)&addr,sizeof(addr)) == -1)
          throw erro;         

 }
/////////////////////////////////////////////////////////////////////////////////////////


void Socket::Aguardar(DWORD porta, DWORD numero)
{
     
        addr.sin_family        = AF_INET;
        addr.sin_port          = htons(porta);
        addr.sin_addr.s_addr   = INADDR_ANY;
     
     erro = "Erro ao configurar localmente o socket.\n";
     if(bind(sock,(struct sockaddr*)&addr,sizeof(addr)) == -1)
       throw erro;
       
       if(UDP)
         return;
             
     erro  = "Erro ao colocar o socket em modo de espera.\n";
         if(listen(sock,numero) == -1)
           throw erro;

 }
/////////////////////////////////////////////////////////////////////////////////////////

void Socket::Aceitar(Socket * novo_sock)
{
     
     if(UDP)
       return;
       
     int size_addr = sizeof(struct sockaddr_in);
     int ret;
   
     if(novo_sock == NULL)
        ret = sock = accept(sock,(struct sockaddr*)&addr,&size_addr);
      else
        ret = novo_sock->sock = accept(sock,(struct sockaddr*)&novo_sock->addr,&size_addr);
       
        erro = "Erro ao aceitar uma conexao pendente.\n";
      if(ret == -1)
       throw erro;
       
 }
/////////////////////////////////////////////////////////////////////////////////////////
 
DWORD Socket::Enviar(string dados)
{
      erro  = "Erro ao enviar dados.\n";
      DWORD ret;

      if(!UDP)
        ret = send(sock,dados.c_str(),dados.size(),0);
      else
        ret = sendto(sock,dados.c_str(),dados.size(),0,(struct sockaddr*)&addr,sizeof(addr));

      if(ret == -1)
        throw erro;
       
        return ret;
     
}

/////////////////////////////////////////////////////////////////////////////////////////

DWORD Socket::Receber(DWORD MAX)
{
     char buf[MAX];
     DWORD ret;
     
     int size_addr = sizeof(struct sockaddr_in);
     
     if(!UDP)
       ret = recv(sock,buf,MAX,0);
     else
       ret = recvfrom(sock,buf,MAX,0,(struct sockaddr*)&addr,&size_addr);
       
       
     buf[ret-1] = '\0';
     
    erro = "Erro ao receber dados.\n";
     if(ret == -1)
       throw erro;
       
     buffer = "";
     
      if(ret)
        buffer = buf;
       
       return ret;

}

/////////////////////////////////////////////////////////////////////////////////////////

string Socket::HostRemoto()
{
       string ret;
       ret = inet_ntoa(addr.sin_addr);
       return ret;
       }
/////////////////////////////////////////////////////////////////////////////////////////

DWORD Socket::PortaRemota()
{

return (DWORD)htons(addr.sin_port);

}       

/////////////////////////////////////////////////////////////////////////////////////////

void Socket::Fechar()
{
     closesocket(sock);
     criado = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////


Códigos de exemplos:
 http://three.fsphost.com/darkside/exemplos_socket.zip

Bye xD

rog

beleza dark side

vc voltou na ativa ?

rog
realty.sys is corrupt :  reboot the universe (Y/N)

whit3_sh4rk

Mto bom ^^

Em breve pretendo iniciar em C++ e seus tutos já estão guardados hehe..

[]s

Mental_Way

Dark_Side,

Muito bom, pois a maneira que vc cita antes os elementos fundamentais do codigo , facilita muito a compreesão do codigo...

Como o whit3_sh4rk, estou começando em c e seues tutoriais estão ajudando muito na otimização de meus programas...

Sem +...
[RitualistaS GrouP]

"Aquele que sabe pouco rapidamente revela isto."