Compartir a través de


Código de cliente solo IPv4

El código siguiente es el archivo Simplec.c, que es un cliente de Windows Sockets de solo IPv4 (se puede encontrar una versión habilitada para IPv6 del archivo Simplec.c en el Apéndice B). Este código solo se proporciona con fines de comparación: use el Apéndice B para obtener un ejemplo de cómo escribir un cliente habilitado para IPv6.

/******************************************************************************\
* simplec.c - Simple TCP/UDP client using Winsock 1.1
* 
*       This is a part of the Microsoft<entity type="reg"/> Source Code Samples.
*       Copyright 1996 - 2000 Microsoft Corporation.
*       All rights reserved.
*       This source code is only intended as a supplement to
*       Microsoft Development Tools and/or WinHelp<entity type="reg"/> documentation.
*       See these sources for detailed information regarding the
*       Microsoft samples programs.
\******************************************************************************/
#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

#define DEFAULT_PORT 5001
#define DEFAULT_PROTO SOCK_STREAM // TCP

void Usage(char *progname) {
    fprintf(stderr,"Usage\n%s -p [protocol] -n [server] -e [endpoint] \
    -l [iterations]\n",
        progname);
    fprintf(stderr,"Where:\n\tprotocol is one of TCP or UDP\n");
    fprintf(stderr,"\tserver is the IP address or name of server\n");
    fprintf(stderr,"\tendpoint is the port to listen on\n");
    fprintf(stderr,"\titerations is the number of loops to execute\n");
    fprintf(stderr,"\t(-l by itself makes client run in an infinite loop,");
    fprintf(stderr," Hit Ctrl-C to terminate it)\n");
    fprintf(stderr,"Defaults are TCP , localhost and 5001\n");
    WSACleanup();
    exit(1);
}

int main(int argc, char **argv) {

    char Buffer[128];
    char *server_name= "localhost";
    unsigned short port = DEFAULT_PORT;
    int retval, loopflag=0;
    int i, loopcount,maxloop=-1;
    unsigned int addr;
    int socket_type = DEFAULT_PROTO;
    struct sockaddr_in server;
    struct hostent *hp;
    WSADATA wsaData;
    SOCKET  conn_socket;

    if (argc >1) {
        for(i=1;i <argc;i++) {
            if ( (argv[i][0] == '-') || (argv[i][0] == '/') ) {
                switch(tolower(argv[i][1])) {
                    case 'p':
                        if (!_stricmp(argv[i+1], "TCP") )
                            socket_type = SOCK_STREAM;
                        else if (!_stricmp(argv[i+1], "UDP") )
                            socket_type = SOCK_DGRAM;
                        else
                            Usage(argv[0]);
                        i++;
                        break;

                    case 'n':
                        server_name = argv[++i];
                        break;
                    case 'e':
                        port = (USHORT) atoi(argv[++i]);
                        break;
                    case 'l':
                        loopflag =1;
                        if (argv[i+1]) {
                            if (argv[i+1][0] != '-') 
                                maxloop = atoi(argv[i+1]);
                        }
                        else
                            maxloop = -1;
                        i++;
                        break;
                    default:
                        Usage(argv[0]);
                        break;
                }
            }
            else
                Usage(argv[0]);
        }
    }
    
    if ((retval = WSAStartup(0x202,&wsaData)) != 0) {
        fprintf(stderr,"WSAStartup failed with error %d\n",retval);
        WSACleanup();
        return -1;
    }
    
    if (port == 0){
        Usage(argv[0]);
    }

    //
    // Attempt to detect if we should call gethostbyname() or
    // gethostbyaddr()

    if (isalpha(server_name[0])) {   /* server address is a name */
        hp = gethostbyname(server_name);
    }
    else  { /* Convert nnn.nnn address to a usable one */
        addr = inet_addr(server_name);
        hp = gethostbyaddr((char *)&addr,4,AF_INET);
    }
    if (hp == NULL ) {
        fprintf(stderr,"Client: Cannot resolve address [%s]: Error %d\n",
            server_name,WSAGetLastError());
        WSACleanup();
        exit(1);
    }

    //
    // Copy the resolved information into the sockaddr_in structure
    //
    memset(&server,0,sizeof(server));
    memcpy(&(server.sin_addr),hp->h_addr,hp->h_length);
    server.sin_family = hp->h_addrtype;
    server.sin_port = htons(port);

    conn_socket = socket(AF_INET,socket_type,0); /* Open a socket */
    if (conn_socket <0 ) {
        fprintf(stderr,"Client: Error Opening socket: Error %d\n",
            WSAGetLastError());
        WSACleanup();
        return -1;
    }

    //
    // Notice that nothing in this code is specific to whether we 
    // are using UDP or TCP.
    // We achieve this by using a simple trick.
    //    When connect() is called on a datagram socket, it does not 
    //    actually establish the connection as a stream (TCP) socket
    //    would. Instead, TCP/IP establishes the remote half of the
    //    ( LocalIPAddress, LocalPort, RemoteIP, RemotePort) mapping.
    //    This enables us to use send() and recv() on datagram sockets,
    //    instead of recvfrom() and sendto()


    printf("Client connecting to: %s\n",hp->h_name);
    if (connect(conn_socket,(struct sockaddr*)&server,sizeof(server))
        == SOCKET_ERROR) {
        fprintf(stderr,"connect() failed: %d\n",WSAGetLastError());
        WSACleanup();
        return -1;
    }

    // cook up a string to send
    //
    loopcount =0;
    while(1) {
        sprintf_s(Buffer,sizeof(Buffer), "This is a small test message [number %d]",loopcount++);
        retval = send(conn_socket,Buffer,sizeof(Buffer),0);
        if (retval == SOCKET_ERROR) {
            fprintf(stderr,"send() failed: error %d\n",WSAGetLastError());
            WSACleanup();
            return -1;
        }
        printf("Sent Data [%s]\n",Buffer);
        retval = recv(conn_socket,Buffer,sizeof (Buffer),0 );
        if (retval == SOCKET_ERROR) {
            fprintf(stderr,"recv() failed: error %d\n",WSAGetLastError());
            closesocket(conn_socket);
            WSACleanup();
            return -1;
        }
        //
        // We are not likely to see this with UDP, since there is no
        // 'connection' established. 
        //
        if (retval == 0) {
            printf("Server closed connection\n");
            closesocket(conn_socket);
            WSACleanup();
            return -1;
        }
        printf("Received %d bytes, data [%s] from server\n",retval,Buffer);
        if (!loopflag){
            printf("Terminating connection\n");
            break;
        }
        else {
            if ( (loopcount >= maxloop) && (maxloop >0) )
                break;
        }
    }
    closesocket(conn_socket);
    WSACleanup();
}