2017-06-16 6 views
-1

ちょうどTCP/IP Sockets in C: Practical Guide for Programmersを使用してCネットワークを開始しました。それは最初peiceだbook(私は合法的な物理コピーを持っていますが、ここでは、無料のオンラインPDF版へのリンクであるとしてブックからコピーすることができませんでし)TCP/IPエコークライアントのハング

#include <stdio.h> //for printf and fprintf 
#include <sys/socket.h> // for socket() , connect(),send(), and recv() 
#include <arpa/inet.h> //for sockaddr_in and inet_addr() 
#include <stdlib.h> //for atoi() 
#include <string.h> //for memset() 
#include <unistd.h> //for close() 

#define RCVBUFSIZE 32 //size of recieve buffer 

void DieWithError(char *errorMessage); //error handling function 

int main (int argc , char *argv[]) 
{ 
    int sock; /*SOcket descriptor*/ 
    struct sockaddr_in echoServAddr; /*Echo server address*/ 
    unsigned short echoServPort; /*Echo server port*/ 
    char *servIP; /*Server IP address (dotted quad)*/ 
    char *echoString; /*string to send to echo server*/ 
    char echoBuffer[RCVBUFSIZE]; /*Buffer for echo string*/ 
    unsigned int echoStringLen; /*Length of string to echo*/ 
    int bytesRcvd , totalBytesRcvd; /*Bytes read in single recv() and total bytes read*/ 

    if((argc < 3) || (argc > 4)) /*Test for correct number of arguments */ 
    { 
     fprintf(stderr , "Usage: %s <Server IP> <Echo Word> [<Echo Port>]\n", argv[0]); 
     exit(1); 
    } 

    servIP = argv[1]; /*first arg: server IP address (dotted quad)*/ 
    echoString = argv[2]; /*Second arg: string echo*/ 

    if(argc == 4) 
     echoServPort = atoi(argv[3]); /*Use given port, if any*/ 
    else 
     echoServPort = 7; /*7 is the well-known port for the echo service*/ 

    /*Create a reliable, stream socket using TCP*/ 
    if((sock = socket(PF_INET , SOCK_STREAM , IPPROTO_TCP)) < 0) 
     DieWithError("Connect() failed"); 

    /*COnstruct the server address structure*/ 
    memset(&echoServAddr , 0 , sizeof(echoServAddr)); /*zero out structure*/ 
    echoServAddr.sin_family = AF_INET; /*Internet address family*/ 
    echoServAddr.sin_addr.s_addr = inet_addr(servIP); /*Server IP address*/ 
    echoServAddr.sin_port = htons(echoServPort); /*Server port*/ 

    /*Establish the connection the echo server*/ 
    if(connect(sock, (struct sockaddr *) &echoServAddr , sizeof(echoServAddr)) < 0) 
     DieWithError("send() sent a differnt number of bytes than expected"); 

    /*Recieve the same string back from the server*/ 
    totalBytesRcvd = 0; 
    printf("Recieved: "); /*setup to print the echoed string*/ 
    while(totalBytesRcvd < echoStringLen) 
    { 
     /* Recieve up to the bufffer size (minus 1 to leave space for a null terminator) 
      bytes from the sender*/ 
     if((bytesRcvd = recv(sock , echoBuffer , RCVBUFSIZE - 1, 0)) <=0) 
      DieWithError("recv() failed or connection closed prematurely"); 
     totalBytesRcvd += bytesRcvd; /*Keep tally of total bytes*/ 
     echoBuffer[bytesRcvd] = '\0'; /*Terminate the string*/ 
     printf(echoBuffer); /*Print the echo buffer*/ 
    } 

    printf("\n"); /*Print a final linefeed*/ 
    close(sock); 
    exit(0); 
} 

void DieWithError(char *errorMessage) 
{ perror(errorMessage); 
    exit(1); 
} 

ブックのコード:私は本のコード例に従っています

:本は、その後コンパイルし、これらの引数を使用してプログラムを実行するために私に指示

TCPEchoClient.c

あるブック内のコードの

我々はコンパイル 場合 この 我々は 次の よう が インターネット アドレス 169.1.1.1と サーバー エコー と を通信することができ TCPEchoClient、 などのアプリケーション : %のTCPEchoClient i。私。 "エコー これ!" 受信 ' エコー これ!

しかし、私が本書からこれらの引数を使用すると、プログラムを実行するとハングするだけです。なぜこれが起こっているのか混乱していますか?どんな助けもありがとうございます。

+0

あなたが提供するIPアドレスはもちろん、サーバーを実行するホストのアドレスにする必要があります。あなたはどこかでサーバーを稼働させていますか? –

+0

他人に読んでもらいたい場合は、コードをインデントしてください。 – Lundin

+0

私は上に行き、インデントします。 – Hexodus

答えて

2

ああ、あなたはコードをコピーしたときに何か非常に重要なことを忘れてしまったようです。実際に何かをサーバーに送信します。

はどこか

if(connect(sock, (struct sockaddr *) &echoServAddr , sizeof(echoServAddr)) < 0) 

と非常に次の行

DieWithError("send() sent a differnt number of bytes than expected"); 

の間では、サーバーにデータを送信するために実際のコードを欠落しているように見えます。

何も送信しないので、サーバはrecvコールで忍耐強く待っています。一方で、決して起こらない返信を待っているあなた自身のrecvコールにこだわっています。これにより、デッドロックが発生し、サーバーとクライアントの両方が他のピアが何かを送信するのを待ちます。

+0

私の愚かな間違いに感謝します。 – Hexodus

関連する問題