2

少しトレント トラッカーhttp://tracker.thepiratebay.orgに接続しようとしています。gethostbyname() が null を返し続けます。これを修正するにはどうすればよいですか? また、このコードに他に何か問題がありますか?

    int sock;
    struct sockaddr_in servAddr; 
    int portNum = 80;

    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
          printf("fail create socket");
          return 0;
    }

    char *path = "http://tracker.thepiratebay.org/";
    struct hostent *hp = gethostbyname(path);   
    if(hp==NULL){
        printf("null");
    else{

        memset(&servAddr, 0, sizeof(servAddr));   
        servAddr.sin_family = AF_INET;                 
        memcpy( (char *) &servAddr.sin_addr.s_addr, (char *)  hp->h_addr, hp->h_length );
        servAddr.sin_port   = htons(portNum);    
    }

    //send request to tracker server 
    if (send(sock, requestToSend, strlen(requestToSend), 0) != strlen(requestToSend)){
        printf("fail send");
        return 0;
    }
4

1 に答える 1

7

ここでの問題はhttp://tracker.thepiratebay.org/、これが URL であることですがgethostbyname()、ホスト名だけが必要です。ホスト名はtracker.thepiratebay.org.

libcurlを使用するだけで、そのすべての HTTP を処理するのがはるかに簡単になります。HTTP サーバーに接続するアプリケーションで libcurl を使用することは非常に一般的です。それは優れたライブラリです。ソケットプログラミングよりも確かに簡単です。

使用するgetaddrinfo()

の現代的な代替手段gethostbyname()は ですgetaddrinfo()。それgethostbyname()はあなたが望むことをしないということではなく、getaddrinfo()考えられるすべての点で単純に優れているということです。

struct addrinfo hint, *ap;
memset(&hint, 0, sizeof(hint));
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
int r = getaddrinfo("tracker.thepiratebay.org", "http", &hint, &ap);

これにより、必要なホストのアドレスが取得されるだけでなく、ポート番号も入力されます。"http"ポートとして使用することも、ポートとして使用することもできます。それらは同じものです (正しいエントリがある"80"限り)。/etc/services

その他の問題

この行は間違っています。

memcpy( (char *) &servAddr.sin_addr.s_addr, (char *)  hp->h_addr, hp->h_length );

が IPv4 アドレスを返したことがわからずgethostbyname()、それを にコピーしようとするのはばかげていstruct sockaddr_inます。IPv6 アドレスが返された場合gethostbyname()は、スタックを破壊しただけであり、プログラムがクラッシュするか、さらに悪いことに、クラッシュしない可能性があります。

IPv4 アドレスが返されることを確認するか、単にから返さhp->h_addrれたジェネリックにコピーします。これは少し醜いですが、それはそれが行く方法です。struct sockaddrmalloc(hp->h_length)

最後に、引数を にキャストするのは間違っていますmemcpy()。エラーではありませんが、間違っています。そうしないと、正当なコンパイラ エラーが抑制される可能性があります。たとえば、誤ってintto をキャストした場合などですchar *

于 2012-12-04T04:01:24.440 に答える