Richard597 Posted January 30, 2016 at 03:59 PM Report Share #592809 Posted January 30, 2016 at 03:59 PM (edited) Bom dia, pessoal do portugal a programar! Pessoal, estou com o caso sobre programacao de socket em C que não estou conseguindo endetender. Se alguém puder me expliicar eu agradeço... Primeiro observem o código a seguir: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <unistd.h> /* headers necessário para o socket*/ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define PORT 2000 int main(){ int Mysocket; struct sockaddr_in Myserv; //###<<< observe esta estrutura. Mysocket = socket(AF_INET, SOCK_STREAM, 0); //criando o sockfd (descriptor) if (Mysocket == -1){ perror("socket "); exit (1); } Myserv.sin_family = AF_INET; // host byte order Myserv.sin_port = htons(PORT); // short, network byte order memset(Myserv.sin_zero, 0x0, 8); // zero the rest of the (definida em string.h) if (bind(Mysocket, (struct sockaddr *)&Myserv, sizeof(struct sockaddr)) == -1){ perror("bind "); exit(1); } listen(Mysocket, 1); getc(stdin); close(Mysocket); printf("\tSocket Finished...\n\n"); return 0; } O problema que estou tendo com este código é na estrutura "struct sockaddr_in Myserv;". Pois notem que ela está declarado dentro da função main(). Porém, quando compilo este código, eu noto que a função bind() retorna -1, pois o perror("bind "); no segundo if é executado. Mas, por outro lado, quando eu coloco aquela estrutura "struct sockaddr_in Myserv;" fora da função main() e recompilo o código, vejo que o bind() não retorna -1, o programa segue até o final. Alguém poderia explicar o por quê isto está acontecendo?? (uso compilador gcc no ubuntu). Edited January 30, 2016 at 04:30 PM by Richard597 Link to comment Share on other sites More sharing options...
pwseo Posted January 30, 2016 at 05:11 PM Report Share #592813 Posted January 30, 2016 at 05:11 PM Não é suposto preencheres o campo .sin_addr.s_addr da tua variável Myserv? De qualquer modo, como não o preenches explicitamente, acontece o seguinte: Se definires a variável dentro da main(), o seu valor será escolhido ao acaso Se definires a variável fora da main(), o seu valor será inicializado a zero (pois é isto que acontece a todas as variáveis em C definidas globalmente, fora de funções Mais ainda, se definires a variável dentro da main e depois colocares .sin_addr.s_addr a zero, o programa funciona. PS.: Não percebo muito de sockets, mas parece-me que aqui estás a inicializar mal as coisas. Link to comment Share on other sites More sharing options...
Richard597 Posted January 30, 2016 at 06:14 PM Author Report Share #592815 Posted January 30, 2016 at 06:14 PM (edited) OK! Valeu pela explicação com relação ao global e ao local. Mas, em alguns códigos que que eu fiz, também coloquei a estrutura dentro da main() e funcionou!!! O problema foi só nesse código que coloquei aí. E com relação ao .sin_addr.s_addr, não coloquei em zero e deu certo com os outros códigos. Agora, em alguns livros que lí, eles indicam colocar o seguinte: memset(Myserv.sin_zero, 0x0, 8); Segundo eles, isso serve para resetar o restante da estrutura sockaddr_in Mas não sei, ao certo, qual é o propósito disto. De qualquer forma vou seguir essa tua orientação de "Zerar" o .sin_addr.s_addr para ver se dar certo. Eu não quiz definir o endereço para socket porque eu estou fazendo o teste localmente e usando nc na porta de escuta do socket e o nmap tmabém para scanear a porta... De qualquer forma, Obrigado pelas dicas... Até breve!!! Edited January 30, 2016 at 06:15 PM by Richard597 Link to comment Share on other sites More sharing options...
pwseo Posted January 30, 2016 at 06:17 PM Report Share #592817 Posted January 30, 2016 at 06:17 PM A chamada ao memset não coloca .sin_addr.s_addr a zero, apenas faz isso ao campo .sin_zero. E se o objectivo é testar localmente, então o melhor é definir o IP como o 127.0.0.1. Link to comment Share on other sites More sharing options...
Richard597 Posted January 30, 2016 at 06:34 PM Author Report Share #592819 Posted January 30, 2016 at 06:34 PM Mas é porque nesse exemplo que fiz, o socket fica só na escuta, aguardando a conexão na porta 2000... Eu ainda não estou configurando ele para aceitar ou entra em conexão remota.. Mas por via das dúvidas eu usei o seguinte: .sin_addr.s_addr = INADDR_ANY; Link to comment Share on other sites More sharing options...
pwseo Posted January 30, 2016 at 07:14 PM Report Share #592820 Posted January 30, 2016 at 07:14 PM Richard597, O IP é sempre definido, quer queiras quer não. O que pode acontecer é deteres um IP com um significado especial, como o 0.0.0.0 ou o 127.0.0.1. Fiz uma modificação ao teu código para me mostrar em que endereço ele está à escuta quando o iniciamos, repara: ~ $ # versão com Myserv dentro da main() ~ $ ./test1 Listening on 253.127.0.0:2000 bind : Cannot assign requested address ~ $ ~ $ # versão com Myserv fora da main() ~ $ ./test2 Listening on 0.0.0.0:2000 A primeira versão falha porque como .sin_addr não foi inicializado, existe lá um valor que o programa assume como sendo o IP onde queres receber ligações. Como esse não é o teu IP, o programa falha. Na segunda versão esse valor é definido para 0, que é convertido no IP 0.0.0.0, permitindo que o programa funcione. Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted January 30, 2016 at 08:16 PM Report Share #592822 Posted January 30, 2016 at 08:16 PM (edited) #include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <unistd.h>/* headers necessário para o socket*/#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#define PORT 2000int main() { int my_socket; // socket descriptor struct sockaddr_in my_address; // endereço a que o socket irá se associar my_socket = socket(AF_INET, SOCK_STREAM, 0); // pedir ao sistema para criar o socket if (my_socket == -1) { // verificar se o pedido foi bem sucedido perror("socket "); exit (1); } memset(&my_address, 0, sizeof(my_address)); // a inicialização a zero deverá ser feita agora my_address.sin_family = AF_INET; // -- host byte order -- ??? // isto é a definição do tipo de endereço, que neste caso é AF_INET<->IPv4 my_address.sin_port = htons(PORT); // -- short, network byte order -- ?? // isto é a porta em que o socket será "pendurado" my_address.sin_addr.s_addr = INADDR_ANY; // <----- o que te disseram para fazer/* já foi dito que isto não faz sentidomemset(Myserv.sin_zero, 0x0, 8); // zero the rest of the (definida em string.h)*/ // pedir ao sistema para associat o socket criado ao endereço pretendido if (bind(my_socket, (struct sockaddr *) &my_address, /* sizeof(struct sockaddr) */ sizeof(my_address)) == -1) { // cuidado !! passar o valor correcto do tamanho do endereço !!! // quanto muito seria "sizeof(struct sockaddr_in)" perror("bind "); exit(1); } // registar o socket para receber ligações externas listen(my_socket, 1); // "flavour" para manter a consola aberta e/ou manter a aplicação aberta getc(stdin); // limpeza close(my_socket); printf("\tSocket Finished...\n\n"); return 0;}[/Code] Edited January 31, 2016 at 09:49 AM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
Richard597 Posted January 31, 2016 at 12:57 AM Author Report Share #592834 Posted January 31, 2016 at 12:57 AM (edited) Ok! Pessoal! pwseo Obrigado pelo as explicação... E HappyHippyHippo valeu por deixar o código mais claro... É porque essas coisas de programação, eu fico aqui tentando aprender por conta própria. Nunca frequentei cursos relacionado à computação e, por isso, não aprendi cada coisa por vez (no devido momento). Aí sempre surge essas dúvidas.. Mais uma vez! obrigado a vocês. Edited January 31, 2016 at 09:08 AM by pwseo nome de utilizador corrigido Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now