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] = "[=11=]";
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 在这两种情况下在服务器端都有正确的值并打印。
write/read?
一定是出了什么问题
我在服务器上也打印了htonl(totalSize),是67371008。
然而客户端收到的值在ntohl之前是2021093988。
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
以下代码将无法正常运行,因为您在修改字符串后再次调用 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
所以现在 write
中的 strlen
将 return 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");
}
编辑:老实说,我不知道错误发生在哪里,所以我只添加大部分相关代码,不确定是否有任何帮助
所以基本上我有两个基本的服务器和客户端进程。 用户指定命令,客户端进程发送消息长度给服务器,服务器执行命令并返回响应消息长度。
这在第一个命令上运行良好(我连续尝试了两次 ls -la),第一个命令上的值为 1028(正确值),第二个命令上错误地为 1685223288(在客户端中)
写入是通过以下代码完成的:
server_handler() {
char str[5000];
char * token = NULL;
unsigned long totalSize = 0;
str[0] = "[=11=]";
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 在这两种情况下在服务器端都有正确的值并打印。 write/read?
一定是出了什么问题我在服务器上也打印了htonl(totalSize),是67371008。 然而客户端收到的值在ntohl之前是2021093988。
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
以下代码将无法正常运行,因为您在修改字符串后再次调用 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
所以现在 write
中的 strlen
将 return 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");
}