使用TCP套接字发送/读取,字节大小异常
我正在尝试实现一个正常工作的HTTP客户机-服务器应用程序,只是为了练习网络编程。使用TCP套接字发送/读取,字节大小异常,c,sockets,tcp,send,recv,C,Sockets,Tcp,Send,Recv,我正在尝试实现一个正常工作的HTTP客户机-服务器应用程序,只是为了练习网络编程。 这两个程序必须遵循以下基本算法: 客户端-发送GET请求 服务器-发送“+OK\r\n” 服务器-以字节为单位发送文件大小 服务器-发送文件 客户端-发送确认 我在阅读部分遇到了很多麻烦,可能是因为我在流媒体上进行了一些肮脏的阅读 以下是我正在使用的2个读取函数: /* Reads a line from stream socket s to buffer ptr The line is stored in pt
这两个程序必须遵循以下基本算法:
客户端-发送GET请求
服务器-发送“+OK\r\n”
服务器-以字节为单位发送文件大小
服务器-发送文件
客户端-发送确认 我在阅读部分遇到了很多麻烦,可能是因为我在流媒体上进行了一些肮脏的阅读 以下是我正在使用的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);
}
而不是
char okMsg[] = "+OK\r\n";
这导致我的行为不明确 long number=0;
long number=0;
for (n=1; n<maxRead+1; n++)
{
nread=recv(s, &number, sizeof(number), 0);
对于(n=1;nlong number=0;
对于(n=1;nlong number=0;
对于(n=1;nlong number=0;
对于(n=1;您必须记住TCP是一种流式协议。这意味着对recv
的调用返回的字节数可能小于请求的字节数。这是readNumber
函数可能无法按预期工作的原因之一。但更大的原因是,当您使用未初始化的局部变量时,您的函数中有(totRead
更具体地说)。“+OK\r\n”是5字节,而不是8字节,所以您可能想知道为什么服务器会给您一个错误的报告。我一直认为,每当我不初始化一个变量时,它都会隐式初始化为零,您能给我举一个代码中未定义行为的例子吗?在函数中声明一个局部变量并打印它,这就是您所要做的一切o来验证行为。全局变量和静态变量都是零初始化的,但从来不是正常的局部变量。我想指出,readline循环非常简单,但可能也是读取数据的最差方式。您为每个字符调用recv。这是一个系统调用。系统调用需要大量CPU周期。更好的方法是使用缓冲并一次读取4K或更多套接字。您必须记住TCP是一种流协议。这意味着对recv
的调用返回的字节数可能小于请求的字节数。这是readNumber
函数可能无法按预期工作的一个原因。但更大的原因是您在t、 当您使用未初始化的局部变量(totRead
更具体地说)。“+OK\r\n”是5字节,而不是8字节,所以您可能想知道为什么服务器会给您一个错误的报告。我一直认为,每当我不初始化一个变量时,它都会隐式初始化为零,您能给我举一个代码中未定义行为的例子吗?在函数中声明一个局部变量并打印它,这就是您所要做的一切o来验证行为。全局变量和静态变量都是零初始化的,但从来不是正常的局部变量。我想指出,readline循环非常简单,但可能也是读取数据的最差方式。您为每个字符调用recv。这是一个系统调用。系统调用需要大量CPU周期。更好的方法是使用缓冲并一次读取4K或更多套接字。您必须记住TCP是一种流协议。这意味着对recv
的调用返回的字节数可能小于请求的字节数。这是readNumber
函数可能无法按预期工作的一个原因。但更大的原因是您在t、 当您使用未初始化的局部变量(totRead
更具体地说)。“+OK\r\n”是5字节,而不是8字节,所以您可能想知道为什么服务器会给您一个错误的报告。我一直认为,每当我不初始化一个变量时,它都会隐式初始化为零,您能给我举一个代码中未定义行为的例子吗?在函数中声明一个局部变量并打印它,这就是您所要做的一切o来验证行为。全局变量和静态变量都是零初始化的,但从来不是正常的局部变量。我想指出,readline循环非常简单,但可能也是读取数据的最差方式。您为每个字符调用recv。这是一个系统调用。系统调用需要大量CPU周期。更好的方法是使用缓冲并一次读取4K或更多套接字。您必须记住TCP是一种流协议。这意味着对recv
的调用返回的字节数可能小于请求的字节数。这是readNumber
函数可能无法按预期工作的一个原因。但更大的原因是您在t、 当您使用未初始化的局部变量(totRead
更具体地说)。“+OK\r\n”是5字节,而不是8字节,所以您可能想知道为什么服务器会给您一个错误的报告。我一直认为,每当我不初始化一个变量时,它都会隐式初始化为零,您能给我举一个代码中未定义行为的例子吗?在函数中声明一个局部变量并打印它,这就是您所要做的一切o来验证行为。全局变量和静态变量都是零初始化的,但从来不是正常的局部变量。我想指出,readline循环非常简单,但可能也是读取数据的最差方式。您为每个字符调用recv。这是一个系统调用。系统调用需要大量CPU周期。更好的方法是要做到这一点,需要使用缓冲并一次读取4K或更多的套接字。
char *okMsg = "+OK\r\n";
char okMsg[] = "+OK\r\n";
long number=0;
for (n=1; n<maxRead+1; n++)
{
nread=recv(s, &number, sizeof(number), 0);