c - hálózat programozása

Fórumok

Üdv!

Szeretnék egy weboldalt elérni a glibc gethostbyname függvényének segítségével a programomon belül, windows / mingw alatt. A kód a 'programozás c nyelven' című könyvből vett példa módosított változata:


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

#define PROGRAM_NAME "foo"

int
main( int argc, char *argv[] )
{
    int
        n       = 0;

    struct hostent
        *host   = NULL;

    if( argc < 2 )
    {
        fprintf(stderr, "usage:\n  " PROGRAM_NAME " <host>\n");
        exit( 1 );
    }

    if( (host = gethostbyname( argv[1] )) == NULL )
    {
        fprintf( stderr, PROGRAM_NAME ": %s\n", strerror( h_errno ) );
        exit( 1 );
    }

    printf( "%s\n", host->h_name );

    for( n = 0 ; host->h_aliases[ n ]   != NULL ; ++n )
        printf( "%s\n", host->h_aliases[ n ] );

    for( n = 0 ; host->h_addr_list[ n ] != NULL ; ++n )
        printf( "%hhu.%hhu.%hhu.%hhu\n",
                host->h_addr_list[n][0],
                host->h_addr_list[n][1],
                host->h_addr_list[n][2],
                host->h_addr_list[n][3]
        );

    return( 0 );
}

A fordítást a következő paraméterekkel végeztem:


gcc foo.c -o foo.exe -Wall -lws2_32

Viszont mikor futtatom a progit, akkor 'Unknown error' üzenettel lép ki ha például a 'google.com' argumentumot használom, de a 'localhost' esetén is (xampp szerver). Néztem wireshark-ban, hogy egyáltalán küld-e kérést, de sajnos nem. Tűzfal ki volt kapcsolva, egyéb hálózatot használó program sem futott (tudtommal), tehát nem értem, hogy miért nem működik. Linux alatt (persze más include-okkal) működött, de hogy mi baja a windows-zal, arra már tippem sincs és a google sem tudott segíteni, ezért fordultam hozzátok segítségért.

Megoldás:

Winsock 2.0 használata esetén a következő kódrészletet kell beilleszteni a socket használata elé:


WSADATA
    wsaData;

if( WSAStartup( MAKEWORD( 2,0 ), &wsaData ) != 0 )
{
    fprintf( stderr, PROGRAM_NAME ": wsastartup failed\n" );
    exit( 1 );
}

Majd ha már nem akarjuk a socket-eket tovább használni, akkor a WSACleanup() függvénnyel zárjuk a kódot.

Hozzászólások

A h_errno szerintem nem dekódolható az strerror-ral.
Erre UNIX-on a hstrerror/herror való. Bár van szumma kb. 4 hibakód, ami ott lehetséges...

Egyébként (látom, megtaláltad a hibát, de erre rá tudtál volna jönni önerőből) a 10093 windows-os hibakód, és ha rákeresel a guglival, hamar meg is találod:

WSANOTINITIALISED
10093
Successful WSAStartup not yet performed.

Either the application has not called WSAStartup or WSAStartup failed. The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks), or WSACleanup has been called too many times.

Beej's guide
Nézd meg a linket, windowson kelleni fog a WsaStartup függvény meghívása szerintem.

Egy "#ifdef WIN32" -vel bastyazd korbe.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

Az előfeldolgozó logikáját nem igazán értem, mert az


#ifdef WIN32
    #include <winsock2.h>
#else
    #include <netdb.h>
#endif

sorokra a


fatal error: netdb.h: No such file or directory

választ adja. Pedig WIN32 definiálva van, ki is próbáltam:


#ifdef WIN32
    printf( "win" );
#else
    printf( "nem win" );
#endif

Persze a kimeneten a "win" jelent meg. Azt nem értem, hogy ha az előfeldolgozó a feltétel kiértékelése után a WIN32 ágat követi, akkor miért hiányolja azokat a fájlokat, amikhez most épp semmi köze nem lenne?
--
Azt akarom, hogy az emberek ne kényszerből tanuljanak, hanem azért, mert tudni akarnak.

Úgy néz ki megvan a hiba: ha az -ansi kapcsolóval fordítom, akkor írja ezt a hibát és félbeszakad a fordítás, -ansi nélkül viszont még csak nem is figyelmeztet a fájlhiányra. Mindenesetre itt a -v kimenete:

ansival: http://www.diffpaste.com/#/859/
ansi nélkül: http://www.diffpaste.com/#/860/

Ismételten jelzem, hogy mingw környezetről van szó! Az -ansi valahogy nem egészen ugyanaz, mint Linux alatt, mert például nem szabványba illő szintaxisra ott figyelmeztet (pl.: változó deklarálása előtt nem hívhatnánk függvényeket), itt viszont nem.
--
Azt akarom, hogy az emberek ne kényszerből tanuljanak, hanem azért, mert tudni akarnak.