1

私は、ジョン・エリクソンによる「ハッキング、搾取の芸術」という本から学んでいますが、彼が提供した単純なコード・サンプルに関して混乱しています。コードは単純なサーバーをセットアップするためのものですが、コンパイルして (エラーなし) コードを実行すると、ハングします。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "hacking.h"

#define PORT 7890   // the port users will be connecting to

int main(void) {
int sockfd, new_sockfd;  // listen on sock_fd, new connection on new_fd
struct sockaddr_in host_addr, client_addr;  // my address information
socklen_t sin_size;
int recv_length=1, yes=1;
char buffer[1024];

if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
    fatal("in socket");

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
    fatal("setting socket option SO_REUSEADDR");

host_addr.sin_family = AF_INET;      // host byte order
host_addr.sin_port = htons(PORT);    // short, network byte order
host_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(host_addr.sin_zero), '\0', 8); // zero the rest of the struct

if (bind(sockfd, (struct sockaddr *)&host_addr, sizeof(struct sockaddr)) == -1)
    fatal("binding to socket");

if (listen(sockfd, 5) == -1)
    fatal("listening on socket");

while(1) {    // Accept loop
    sin_size = sizeof(struct sockaddr_in);
    new_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);
    if(new_sockfd == -1)
        fatal("accepting connection");
    printf("server: got connection from %s port %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
    send(new_sockfd, "Hello World!\n", 13, 0);
    recv_length = recv(new_sockfd, &buffer, 1024, 0);
    while(recv_length > 0) {
        printf("RECV: %d bytes\n", recv_length);
        dump(buffer, recv_length);
        recv_length = recv(new_sockfd, &buffer, 1024, 0);
    }
    close(new_sockfd);
}
return 0;
}

ぶら下がっている場所を見つけるために少しprintf()を実行しましたが、この行にあることがわかりました

sin_size = sizeof(struct sockaddr_in);

私の環境に関係があるのか​​ 、それとも私が見逃しているものがあるのか​​ はわかりません。本が使用する環境は更新できなくなりました (Ubuntu の一部の古いバージョン)。なので、現在は最新のものを使用しています。

プログラムが動作しない理由を誰か説明してもらえますか?

また、ネットワークの章を学習する前に知っておく必要がある基本事項があれば、教えてください。

4

3 に答える 3

2

このプログラムは、 がクライアント プログラムから着信接続を受信したaccept後、回線が開始されるまで先に進みません。sizeofprintf は、accept が呼び出されたがブロックされたことを示しています。

このサーバー プログラムに接続するには、適切なオプション (IP / ポート) を使用してクライアントをコンパイルおよび実行する必要があります。

更新 192.168.42.248 が本からのものである場合、おそらく間違った IP に接続しようとしています。試してみてくださいtelnet 127.0.0.1 7890

于 2013-02-14T05:27:17.707 に答える
2

これはサーバーであり、ポート 7890 に接続するまで「ハング」します。それがプログラムの要点です (詳細accept()については、接続を待機しているためブロックされます)。

unix を実行していると仮定して、echo "hi there" | nc localhost 7890実行中に同じマシンから端末を入力してみてください。どのように「ブロック解除」されるかがわかります。

于 2013-02-14T05:30:10.963 に答える
0

スレッド内を飛び交うすべてのコメントで、次のコマンドラインを使用してtelnetに接続することをお勧めします。telnet localhost 7890

telnetは、このホストで接続するホストと接続するポートを引数として取ります。「localhost」の使用は、ループバックIP127.0.0.1の使用に似ています。

サーバーに接続することで「ハング」が解決するのはなぜですか?プログラミング環境のマニュアルページまたはその他のドキュメントで読むことができるように、acceptはブロックされています。これは、クライアントが接続するまで関数が戻らないことを意味します。接続後、関数は、通信に使用できる接続クライアント用に作成されたソケットへのハンドルを返します。

于 2013-02-14T05:41:23.860 に答える