2014-04-14 152 views
0

我试图实现一个工作的HTTP客户端 - 服务器应用程序只是为了使网络编程练习。
2.程序必须遵循这个基本算法:
CLIENT - 发送GET请求
服务器 - 发送 “+ OK \ r \ n” 个
服务器 - 以字节为单位发送的文件大小
服务器 - 将文件发送
客户端 - 发送ACK使用TCP套接字发送/读取,字节大小异常

我在阅读部分有很多麻烦,可能是因为我在流上执行了一些脏读。

这些是我使用的2读取功能:

/* Reads a line from stream socket s to buffer ptr 
The line is stored in ptr including the final '\n' 
At most maxlen chasracters are read*/ 
int readline (SOCKET s, char *ptr, size_t maxlen) 
{ 
    size_t n; 
    ssize_t nread; 
    char c; 

    for (n=1; n<maxlen; n++) 
    { 
     nread=recv(s, &c, 1, 0); 
     if (nread == 1) 
     { 
      *ptr++ = c; 
      if (c == '\n') 
       break; 
     } 
     else if (nread == 0) /* connection closed by party */ 
     { 
      *ptr = 0; 
      return (n-1); 
     } 
     else   /* error */ 
      return (-1); 
    } 
    *ptr = 0; 
    return (n); 
} 

和:

int readNumber(SOCKET s, long *num, int maxRead) 
{ 
    size_t n; 
    ssize_t nread; 
    int totRead; 
    long number=0; 
    for (n=1; n<maxRead+1; n++) 
    { 
     nread=recv(s, &number, sizeof(number), 0); 
     if (nread == sizeof(number)) 
     { 
      totRead+=nread; 
      *num = number; 
     } 
     else if (nread == 0) /* connection closed by party */ 
     { 
      *num = 0; 
      return (n-1); 
     } 
     else   /* error */ 
     { 
      printf("nread = %d\n", nread); 
      return (-1); 
     } 
    } 
    return (totRead); 
} 

这是其中i收到+ OK消息,然后将该文件的主要的片断大小:

memset(rbuf,0,sizeof(rbuf));  //rbuf is the buffer where is store the read 
    printf("waiting for response...\n"); 
    result = readline(s, rbuf, sizeof(rbuf)); //reading function is above 
    printf("Byte read(okMsg) = %d\n", result); 
    if (result <= 0) 
    //ERROR MANAGEMENT 
    { 
     printf("Read error/Connection closed\n"); 
     closesocket(s); 
     SockCleanup(); 
     exit(1); 
    } 
    else 
    { 
     long fileLength=0; 
     unsigned char *fBuf; 
     //RECEIVE OK 
     if(!strcmp(rbuf,"+OK\r\n")) 
     { 
      puts("+OK\n"); 
      //RECEIVE FILE LEN 
      int nw = readNumber(s, &fileLength, 1); //reading function is above 
      printf("Byte read(fDim) = %d\n", nw); 
      printf("File is %ld bytes long\n", fileLength); 
      if(nw >0) 
      { 
       // RECEIVE FILE 

      } 
     } 
    } 

当我发送“+ OK \ r \ n”字符串服务器告诉我,它发送8个字节,但是当我读仅在6个字节后才能找到'\ 0'字符。 顺便说一句,它读取正确的消息,但是当我尝试读取文件大小(这是一个长),它给了我一个错误的数字。
我认为流缓冲区很脏,而且我正在读取不是文件大小一部分的2个字节,但我不明白为什么会发生这种情况。

请问我更多的信息,如果我不够清楚。

求助:
谢谢大家的回答! 你让我有正确的心态去理解错误。
模样的问题是,这个声明在服务器:

char *okMsg = "+OK\r\n"; 

,而不是

char okMsg[] = "+OK\r\n"; 

导致我一个未定义的行为。

+0

你必须记住,TCP是一个流媒体协议。这意味着对'recv'的调用可能返回的请求数少于所请求的字节数。这是* one *原因你的'readNumber'函数*可能*不能按预期工作。但更重要的原因是因为当你使用未初始化的局部变量(更具体地说是'totRead')时,你有[*未定义行为*](http://en.wikipedia.org/wiki/Undefined_behavior)。 –

+0

“+ OK \ r \ n”是5个字节,而不是8个,所以你可能想弄清楚为什么你的服务器给你一个错误的报告。 –

+0

我一直认为,只要我不初始化一个变量,它就会被隐式初始化为零,你能否让我在我的代码中定义一个未定义行为的例子? – NLK511

回答

3
long number=0; 
for (n=1; n<maxRead+1; n++) 
{ 
    nread=recv(s, &number, sizeof(number), 0); 

你忘了设计和实施协议到您的服务器和客户端之间进行数据。因为TCP提供了一个字节流,所以你的协议应该被定义为一个字节流。

有多少个字节表示这个数字? “不管多长时间的字节占用我的平台”是一个很好的答案?第一个字节的语义是什么意思? “无论在我的平台上”长“的第一个字节意味着什么”一个好的答案?

A 答案是,“大小应该以小尾数字节顺序作为4字节无符号整数传递”。然后确保您的代码以该格式发送和接收。