sockets [RESOLVIDO]

1. sockets [RESOLVIDO]

Paulo
paulo_moc

(usa Ubuntu)

Enviado em 16/09/2012 - 21:44h

Olá pessoal, estou com uma dúvida em código, quem puder da uma olhada nele...

Servidor::Servidor(int porta)
{
sock = socket(AF_INET, SOCK_STREAM, 0);

if(sock == -1)
throw(socket_exception());

bzero(&local, sizeof(local));
local.sin_family = AF_INET;
local.sin_port = htons(porta);
local.sin_addr.s_addr = INADDR_ANY;
bzero(&(local.sin_zero), 8);

int tam = sizeof(struct sockaddr_in);
bind(sock, (struct sockaddr*)&local, sizeof(struct sockaddr));

listen(sock, 1);

accept(sock, (struct sockaddr*)&remoto, (socklen_t*)&tam);
}

tem alguma coisa errada nesse código? eu compilei e coloquei para ele auguardar connexão na porta 20000 e abri um socket no windows que se conecta no ip de minha internet na porta 20000 e eles não se conectam, eu já testei o sokcet do windows em um site e ele conseguiu se conectar, mas eu não to conseguindo me conectar a esse, então se alguém puder me ajudar eu aradeço.


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 17/09/2012 - 01:27h

O endereço IP é um número de 32 bits, ou quatro bytes. Por uma questão de eficiência interna, muitas implementações aproveitam o fato de que os tipos int e unsigned (ou, mais modernamente, int32_t e uint32_t) também têm quatro bytes de comprimento e representam os endereços como números inteiros. Assim sendo, se você mandar imprimir o número inteiro usado para representar o IP aaa.bbb.ccc.ddd, terá um número cujo valor será aaa*2^24+bbb*2^16+ccc*2^8+ddd.

Se quiser converter de inteiro para a representação aaa.bbb.ccc.ddd, use inet_ntoa(). Para fazer o contrário, use inet_aton().

Tome, porém, cuidado com uma coisa: algumas funções -- particularmente essas que eu acebi de indicar -- usam os quatro bytes com os endereços dispostos na ordem como eles trafegam na rede (isto é: o byte mais significativo -- o aaa do exemplo acima -- é o primeiro dos quatro bytes). Isso difere da representação nativa de inteiros em muitas das CPUs de PCs (como os nossos PCs com processador Intel, que colocam o byte menos significativo na frente). Para converter da representação nativa para a de rede, você deve usar htonl(); já o reverso se faz com ntohl().

Ideia semelhante vale para as portas. Mas como as portas usam apenas 16 bits (dois bytes), a conversão se faz com htons() e ntohs().

3. Re: sockets [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 16/09/2012 - 22:57h

Seu código tem alguns problemas, sim, a saber:

- Seria bom que o parâmetro porta fosse de um tipo que o limitasse garantidamente a inteiro sem sinal de 16 bits (num compilador de 32 bits, isso normalmente é unsigned short, mas se você estiver usando um compilador que tenha <cstdint> ou <stdint.h>, pode usar uint16_t). Com isso, você ajudaria a evitar eventuais "surpresas" devidas a número de porta nemor que zero ou maior que 65535, que um int acomoda sem problemas.

- Prefira usar memset() em lugar de bzero(), pois esta última não faz parte de padrão algum, e está marcada como obsoleta no POSIX (por exemplo: bzero(&local, sizeof(local)) deve virar memset(&local, 0, sizeof local)).

- Aquela segunda chamada a bzero() é desnecessária e, na verdade, perigosa. Remova-a completamente e sem pena.

- Apesar do cast no segundo argumento de bind() (que é necessária porque o C não tem herança de classes, como tem o C++), o terceiro argumento deve ser o tamanho do tipo original, antes do cast (i.e. você deve usar «sizeof local»).

- Se você declarar tam como socklen_t, não precisará fazer o cast.



Mesmo assim, é possível que o erro não seja no seu código. Se você estiver com sua máquina atrás de um firewall, pode ser que as tentativas de conexão estejam simplesmente sendo bloqueadas. De modo semelhante, se você estiver atrás de um roteador de Internet, o IP publicado pelo roteador estará nele, não na sua máquina, e você talvez tenha que criar um redirecionamento na configuração do roteador se quiser que alguém de fora da sua rede eventualmente se conecte no seu programa.


4. Re: sockets [RESOLVIDO]

Paulo
paulo_moc

(usa Ubuntu)

Enviado em 16/09/2012 - 23:31h

a sim cara, valeu as dicas, mas na conexão, eu ja tinha feito um programa assim em java e funcionou direitinho, a unica que coisa que mudou agora é que agora to usando o ubuntu, e nos programas do java eu tava suando o windows7, isso altera alguma coisa?


5. Re: sockets [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 16/09/2012 - 23:40h

Tente as dicas que eu lhe passei, pois pode ser que sejam suficientes para resolver o problema.

Se ainda não for, teste o seu programa em Java no Linux (você provavelmente nem terá de recompilá-lo, pois o arquivo .class deve ser interpretado por qualquer JVM).


6. Re: sockets [RESOLVIDO]

Paulo
paulo_moc

(usa Ubuntu)

Enviado em 16/09/2012 - 23:46h

caramba, acho que exclui eles, mas vou criar outro aqui, e já te falo a resposta...
=]


7. Re: sockets [RESOLVIDO]

Paulo
paulo_moc

(usa Ubuntu)

Enviado em 17/09/2012 - 00:45h

eu consegui aqui, tava usando o ip errado, eu tava usando um que eu busquei pelo site meu ip, mas já coloquei o certo e tá tudo bem.

ei cara se pudesse me dizer como pego ip do cliente...

eu tentei assim :

remoto.sin_addr.s_addr;

já que quando o cliente se conecta ele usa a função accept com o ip dele, e na accept eu uso o remoto para obter o ip dele, mas apareceu um númer muito grande aqui, eu terinha que usar um função para obter o ip? porque eu tenho que usar a inet_addr(); para atribuir um ip ao s_addr certo? que função seria essa?


8. Re: sockets [RESOLVIDO]

Paulo
paulo_moc

(usa Ubuntu)

Enviado em 17/09/2012 - 01:43h

eu usei :

return inet_ntoa(remoto.sin_addr);

ele imprimiu 1.0.0.0, então usei :

htonl(remoto.sin_addr.s_addr);

e ele imprimiu : 16777216


9. Re: sockets [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 17/09/2012 - 17:53h

É claro que sim. Você está imprimindo os quatro bytes que compõem o inteiro de uma vez só. Se quiser imprimir byte a byte, mande imprimir byte a byte. E se quiser a representação em texto, use inet_ntoa(), como eu disse.

Compile o rode o programa abaixo, para ter uma ideia.

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>

int main(void){
struct in_addr addr;

inet_aton("1.2.3.4", &addr);
printf(
"Resultado de inet_aton(\"1.2.3.4\", &addr):\n"
" - addr.s_addr: %08X\n"
" - htonl(addr.s_addr): %08X\n\n",
addr.s_addr, htonl(addr.s_addr)
);

addr.s_addr=htonl(INADDR_LOOPBACK); /* 127.0.0.1 */
printf(
"inet_aton(addr): %s (tendo feito addr.s_addr=htonl(INADDR_LOOPBACK);)\n"
" - addr.s_addr: %08X\n"
" - htonl(addr.s_addr): %08X\n",
inet_ntoa(addr), addr.s_addr, htonl(addr.s_addr)
);

return 0;
}



10. Re: sockets [RESOLVIDO]

Paulo
paulo_moc

(usa Ubuntu)

Enviado em 17/09/2012 - 21:29h

Valeu ae cara... =] me ajudou bastante...






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts