簡體   English   中英

htonl / ntohl在第二個命令上的值不正確?

[英]htonl/ntohl not correct value on second command?

編輯:老實說,我不知道錯誤發生在哪里,所以我只會添加大多數相關代碼,不確定是否有任何幫助

所以基本上我有兩個基本的服務器和客戶端進程。 用戶指定一個命令,然后客戶端進程將消息的長度發送到服務器,服務器執行該命令並發送回響應的消息長度。

這在第一個命令上效果很好(我連續嘗試了兩個ls -la),第一個命令的值是1028(正確值),第二個命令的值是1685223288錯誤(客戶端)

使用以下代碼完成寫入:

server_handler() {
char str[5000];
char * token = NULL;
unsigned long totalSize = 0;
str[0] = "\0";
totalSize = htonl(totalSize); // Correct size already calculate
if((result = write(clientFD, (char *) &totalSize, sizeof(totalSize)) < 0))
{
     printf("Failed sending size to client\n");
     exit(-1);
}
//Here the server starts sending the results to the client
token = strtok(str, "\n"); // str array contains the results
while(token != NULL)
{
     token[strlen(token)] = '\n';
     write(clientFD, token, strlen(token));
     token = strtok(NULL, "\n);
}

讀取是通過以下方式在客戶端進程中完成的:

static void handle_reply() 
{
char * revBuf = 0;
unsigned long int bytesRead = 0;
unsigned long bufferlen = 0;
while(1) 
{
    result = read(socketFD, (char *) &bufferlen, sizeof(bufferlen));
    bufferlen = ntohl(bufferlen);
    recvBuf = malloc(bufferlen);
   //Here client starts reading results
    while(bytesread < bufferlen)
    {
        result = read(socketFD, recvBuf, bufferlen);
        printf("recvBuf: %s\n", recvBuf);
        bytesRead = strlen(recvBuf) + bytesRead;
    }
    free(recvBuf);
    bufferlen = 0;
   client_handler(); //calls Function that asks for new command
}
}

我的問題: 為什么在第一個命令之后我在命令上接收到錯誤的值?我已經驗證了在兩種情況下都可以打印的結果,totalSize在服務器端具有正確的值。 在寫/讀過程中一定出了什么問題?

我還在服務器上打印了htonl(totalSize),它是67371008。但是,在客戶端收到的值在ntohl之前是2021093988。

以下代碼無法正常工作,因為您在修改字符串后再次調用strlen

token = strtok(str, "\n");
while(token != NULL)
{
    token[strlen(token)] = '\n';
    write(clientFD, token, strlen(token));
    token = strtok(NULL, "\n");
}

為了說明,假設str最初是"hello\\nworld\\n" 用十六進制表示

 68 65 6c 6c 6f 0A 77 6f 72 6c 64 0A 00
                ^---- the first newline

strtok之后

 68 65 6c 6c 6f 00 77 6f 72 6c 64 0A 00
                ^---- strtok changed it to a NUL

在行token[strlen(token)] = '\\n'之后

 68 65 6c 6c 6f 0A 77 6f 72 6c 64 0A 00
                ^---- you changed it back to a newline

因此現在writestrlen將返回12,因此write將發送12個字節,而不是您期望的6個字節。 可以這樣調用一次strlen來解決此問題

token = strtok(str, "\n");
while(token != NULL)
{
    size_t length = strlen(token);
    token[length] = '\n';
    write(clientFD, token, length);
    token = strtok(NULL, "\n");
}

htonl和ntohl是32位...

  uint32_t htonl(uint32_t hostlong);
  uint32_t ntohl(uint32_t netlong);

看看使用64位系統的程序中的大整數會發生什么。

#include <stdio.h>

int main(int argc, char** arg)
{
  unsigned long bufferlen = 0;
  unsigned long totalSize = 1024;
  sscanf(arg[1],"%lld",&totalSize);
  printf("%lld  %llx\n", totalSize,totalSize);

  totalSize = htonl(totalSize); // 32 <-> 64bits .
  bufferlen = ntohl(totalSize);

  printf("%lld %llx %lld %llx\n", totalSize,totalSize,bufferlen,bufferlen);

}

測試它:

./test 111111111111111
111111111111111  650e124ef1c7
-940487150 ffffffffc7f14e12 307163591 124ef1c7

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM