clisock.c

Go to the documentation of this file.
00001 /*****************************************************
00002 Programa para testar comunicacao usando sockets
00003 cliente
00004 
00005 Versao multiplataforma (Funciona e Linux e em Windows)
00006 
00007 Marcos A. Stemmer
00008 -------
00009 Ao fazer o projeto no Dev-cpp acrescente a biblioteca libwsock32.a
00010         No menu Project
00011         Submenu Project Options
00012         Tab     Parameters
00013         Botao   Add Library Object
00014         Selecionar o arquivo:
00015                 C/Dev-Cpp/lib/libwsock32.a
00016  *****************************************************/
00017 #include <stdio.h>
00018 
00019 #ifdef unix
00020 #include <string.h>
00021 #include <errno.h>
00022 #include <stdlib.h>
00023 #include <unistd.h>
00024 #include <sys/types.h>
00025 #include <sys/socket.h>
00026 #include <netdb.h>
00027 #include <netinet/in.h>
00028 #define closesocket close
00029 #else
00030 #include <winsock2.h>
00031 #endif
00032 #define MAXMSG 512
00033 
00034 
00035 /* Rotina geral de tratamento de erro fatal
00036    escreve a mensagem e termina o programa */
00037 void erro_fatal(char *mensagem)
00038 {
00039         printf("%s:%s\n",mensagem,strerror(errno));
00040         exit(EXIT_FAILURE);
00041 }
00042 
00043 
00044 /* Cria um soquete e estabelece a conexão */
00045 int cria_soquete(const char *hostname, int port)
00046 {
00047         int sock;
00048         struct hostent *hostinfo;
00049         struct sockaddr_in sockinfo;
00050 
00051         sock=socket(PF_INET, SOCK_STREAM, 0);
00052         if(sock < 0) erro_fatal("socket");
00053 
00054         sockinfo.sin_family=AF_INET;
00055 
00056         /* Configura a porta de serviço do socket */
00057         /* A função htons converte números do host para o formato padrão da internet */
00058         sockinfo.sin_port=htons(port);
00059 
00060         /* Pede informações a partir do nome do host */
00061         hostinfo=gethostbyname(hostname);
00062 
00063         if(hostinfo==NULL) {
00064                 fprintf(stderr,"%s: Unknown host\n", hostname);
00065                 exit(EXIT_FAILURE);
00066         }
00067 
00068         /* Coloca o IP do host no sin_addr */
00069         sockinfo.sin_addr= *(struct in_addr *)hostinfo->h_addr;
00070 
00071         /* conecta com o host */
00072         if(connect(sock, (struct sockaddr *)&sockinfo, sizeof(sockinfo)) < 0)
00073                 erro_fatal("Connect (client)");
00074         return sock;
00075 }
00076 
00077 /* Espera pela chegada de dados no soquete */
00078 /* Retorna 0 em caso de timeout */
00079 int espera(int sock, int tempo)
00080 {
00081         struct timeval timeout;
00082         fd_set sock_fd_set;
00083         int r;
00084 
00085         timeout.tv_sec=tempo;
00086         timeout.tv_usec=0;
00087 
00088         FD_ZERO(&sock_fd_set);
00089         FD_SET(sock,&sock_fd_set);
00090 
00091         r=select(FD_SETSIZE, &sock_fd_set, NULL, NULL, tempo>0? &timeout: NULL);
00092 
00093         if(r<0) erro_fatal("select");
00094         return r;
00095 }
00096 
00097 /* Escreve uma mensagem no soquete. Funciona apenas para mensagens de texto.
00098 Para dados crus, use "send" diretamente */
00099 int escreve_soq(int sock, char *mensagem)
00100 {
00101         int n;
00102 
00103         n = send(sock, mensagem, strlen(mensagem)+1,0);
00104 
00105         if(n < 0) erro_fatal("write");
00106         return n;
00107 }
00108 
00109 
00110 /*
00111 Programa principal:
00112 recebe o nome do host na linha de comando
00113 envia uma mensagem e espera receber uma resposta
00114  */
00115 int main(int argc, char **argv)
00116 {
00117         int soq, nbytes;
00118         char *hostname;
00119         char buf[MAXMSG];
00120 
00121 #ifndef unix
00122         WSADATA wsaData;
00123         if(WSAStartup(MAKEWORD(1,1),&wsaData)) {
00124                 fputs("Erro no WAStartup\n",stderr);
00125         }
00126 #endif
00127 
00128         /* O nome do host vem da linha de comando ou é host local "127.0.0.1" */
00129         hostname = argc > 1? argv[1]: "127.0.0.1";
00130 
00131         /* Cria o soquete com o nome do host e o numero da porta */
00132         soq = cria_soquete(hostname, 5555);
00133 
00134         do      {
00135                 printf("Mensagem=");
00136                 fgets(buf, MAXMSG, stdin);
00137 
00138                 if(*buf < ' ') break;
00139 
00140                 /* Envia uma mensagem pro soquete */
00141                 escreve_soq(soq, buf);
00142 
00143                 /* Espera pela resposta */
00144                 if(espera(soq,5)==0) erro_fatal("Ninguem responde");
00145 
00146                 /* Le a resposta */
00147                 nbytes = recv(soq, buf, MAXMSG, 0);
00148 
00149                 if(nbytes<0) erro_fatal("read");
00150 
00151                 /* Escreve na saída padrão qual foi a resposta recebida */
00152                 printf("\nRecebi a seguinte resposta do servidor:\n%s\n", buf);
00153         } while(1);
00154 
00155         closesocket(soq);
00156         return 0;
00157 }