Introdução

Este programa de demonstracao estabelece um conexao socket para um servidor de ECHO em "outro computador" usando o protocolo TCP. Ele estabelece a comunicao , entao le uma linha da entrada padrao , envia esta linha para o Servidor Echo pelo socket e le a resposta do Echo. Isto é repetido ate se digitar a linha "quit".

 

Programa usando Windows Socket


/*
SOCKPROG.CPP
A interface do aplicativo e via "Microsoft C++ QuickWin
text window."


Testado e compilado no Microsoft Visual C++ 1.0 Standard Version

Copyright 1995 by Ken Coviak
Prepared for CS 671, Grand Valley State University
traduzido por Alex Borges.
original com instrucoes e arquivos para downlod
http://www.csis.gvsu.edu/~erickson/NetworkingArchives/WindowsSockets/KenCoviak/winsockp.html
*/


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#include <winsock.h>

#define NUL             '\0' /* ASCII NUL character */ 



/* function prototypes = independente da aplicao, sempre aparece */


void do_sock(
    SOCKET sock );          /* socket to read and write */
    
void pWSAerror(
    char *text );           /* error message text */

/* programa principal */

void main()
    {
    char *argv[] = {        /* fake command argument list */
      "sockprog",               /* this program's name */
      "river.it.gvsu.edu",      /* host name, se quiser testar na mesma maquina use "localhost" ou endereco de loopback 127.0.0.1 */
      "echo"                    /* echo service name */
      };


/* estruturas que aprecem indepentede da aplicacao */

    WORD   wVersionRequested; /* requested version WinSock API */ 
    WSADATA wsadata;        /* dados da Windows Sockets API*/
    SOCKET sock;            /* descritp de socket */
    struct hostent FAR *hp; /* ptr para informacoes do host  */
    struct servent FAR *sp; /* ptr para inf. do servico */
    struct sockaddr_in server; /* endereco do socket e porta */

    int    stat;            /* valor de status  */



    /* Enviar uma msg para a janela de texto (stdin/stderr/stdout) */
    printf( "SOCKPROG Windows Socket Demo Program (QuickWin).\n" );


/*------------------------------------------------------*/
/* Incializar a Windows Sockets API. independente da aplicacao */
/* Procurando por API version 1.1 */
/*------------------------------------------------------*/


    printf( "Starting WinSock API...\n" );    
    wVersionRequested = 0x0101;
    stat = WSAStartup( wVersionRequested, &wsadata );
    if (stat != 0)
        {
        printf( "No usable WINSOCK.DLL found\n" );
        exit( 1 );
        }
    else if (LOBYTE( wsadata.wVersion) != 1  &&
             HIBYTE( wsadata.wVersion) != 1)
        {
        printf( "WINSOCK.DLL does not support version 1.1\n" );
        WSACleanup();
        exit( 1 );
        }
        
    printf("WINSOCK description: %s\n", wsadata.szDescription);
    printf("WINSOCK vendor info: %s\n", wsadata.lpVendorInfo);




/*------------------------------------------------------*/
/* Criar o socket - independente da aplicacao */
/* para udp use SOCK_DGRAM e para TCP SOCK_STREAM */
/*------------------------------------------------------*/

   
    sock = socket( AF_INET, SOCK_STREAM, 0 );
    if (sock == INVALID_SOCKET)
        {
        pWSAerror( "could not create socket" );
        WSACleanup();
        exit( 1 );
        }
 


/*------------------------------------------------------*/
/* Conectar (e associar) o socket ao servico e servidor.*/
/* Tambem independente da aplicacao */
/*------------------------------------------------------*/

    
    hp = gethostbyname( argv[1] ); /* pegar o host pelo nome . se for a maquna local = "localhost"*/
    if (hp == NULL)
        {
        printf( "could not get host by name %s\n", argv[1] );
        pWSAerror( "no host" );
        WSACleanup();
        exit( 1 );
        }
        
    memset( &server, 0, sizeof(server) );
    memcpy( &server.sin_addr, hp->h_addr, hp->h_length );
    server.sin_family = hp->h_addrtype;
    
    sp = getservbyname( argv[2], "tcp" );
    if (sp == NULL)
        {
        if (isdigit(*(argv[2])))
            /* get service by number */
            /* we need to swap byte order here */
            server.sin_port = htons( atoi(argv[2]) );
        else
            {
            printf( "could not find tcp service %s\n", argv[2] );
            pWSAerror( "no service" );
            WSACleanup();
            exit( 1 );
            }
        }
    else
        server.sin_port = sp->s_port;
       
    stat = connect( sock, (const struct sockaddr FAR *)&server,
      sizeof(server) );
    if (stat != 0)
        {
        pWSAerror( "could not connect" );
        WSACleanup();
        exit( 1 );
        }
        
    printf( "successful socket established\n" );
 


/*------------------------------------------------------*/
/* Ler da entrada padrao e enviar pelo socket */
/* ler do socket e enviar para a saida padrao */
/* essa é a aplicacao e é a parte que muda realmente */
/*------------------------------------------------------*/

       
    do_sock( sock );
    


/*------------------------------------------------------*/
/* Terminar o programa fechando o socket, etc */
/*------------------------------------------------------*/


    shutdown( sock, 2 );
    closesocket( sock );
    WSACleanup();
    exit( 0 );
    }



/* esta é a funcao que implemtnea a aplicacao */
/* ler do stdin e escrever p/ o socket e o inverso */
/* assume-se que o nro. de caracteres enviados e o mesmo */
/* que vamos receber. pode acontecer espera infinita neste ponto*/


#define MAXLINE 256

void do_sock(
    SOCKET sock )               /* socket para ler e escrever = indepentede da aplicacao quando se quer ler ou escrever*/
    {
    int loopy;                  /* loop control */
    int nb;                     /* numero de bytes */
    char buffer[MAXLINE];       /* linha lida */
    int bufcnt;                 /* no. de carc. no buffer */                            
    char sockbuf[MAXLINE];      /* carac.  lidos do socket */
    int sockcnt;                /* no. de  carac no sockbuf */

    /* Repeat until "quit" is entered. */
    loopy = 1;
    while (loopy) 
        {



/*--------------------------------------------------*/
/* Pega uma linha da stdin. se for a string */
/* "quit" ou uma linha vazia, vamos terminar a aplicacao */
/* De outra forma,vamos continuar e enviar */
/* a linha para o servidor de echo */
/*--------------------------------------------------*/

        
        printf("Enter command for server (or quit)\n");
        if (gets( buffer ) == NULL)
            loopy = 0;
        else if (strcmp( buffer, "quit" ) == 0)
            loopy = 0;
        else
            {



/*----------------------------------------------*/
/* envia a linha para para o servidor ECHO */
/*----------------------------------------------*/

            bufcnt = strlen( buffer );
            nb = send( sock, buffer, bufcnt, 0 );
            if (nb != bufcnt)
                {
                pWSAerror( "error writing to socket" );
                return;
                }
           



/*----------------------------------------------*/
/* le a resposta do servidor de Echo */
/* Note que se nao temos o nro esperado de caracteres */
/* de volta, vamos esperar indefinidamente */
/*----------------------------------------------*/

            sockcnt = 0;
            while (sockcnt < bufcnt)
                {
                nb = recv( sock, &sockbuf[sockcnt], 
                  MAXLINE-sockcnt-1, 0 );
                if (nb == SOCKET_ERROR)
                    {
                    pWSAerror( "error reading from socket" );
                    return;
                    }
                else if (nb == 0) /* socket closed by server */
                    return;
                else              /* read OK, inc char count */
                    sockcnt += nb;
                    
                /*------------------------------------------*/
                /* Escreve a resposta para saida padrao.    */
                /*------------------------------------------*/
                sockbuf[sockcnt] = NUL;
                printf( "%s\n", sockbuf );
                } 
            }     
            
        } /* end while loopy */
    return;
    }



/* A funcao pWSAerror é usada para imprimir um Windows Sockets*/
/* API error message. Esta funcao é usada no lugar de perror */
/* porque a WinSock API retorna seus erros via errno */

 
void pWSAerror(
    char *text )            /* error message text to display */
    {
    int err;                /* Winsock error code */
    
    err = WSAGetLastError();
    printf( "%s, error %d\n", text, err );
    
   
    return;
    }