5

我正在向自己介绍 C/C++ 中的套接字编程,并且正在使用send()recv()通过套接字在客户端和服务器程序之间交换数据TCP

以下是我的代码的一些相关摘录:

服务器.c

char recv_data[1024];

// Socket setup and so on ommited...

bytes_recieved = recv(connected, recv_data, 1024, 0);
recv_data[bytes_recieved] = '\0';

客户端.c:

char send_data[1024];

// Setup ommited...

send(connected, send_data, strlen(send_data), 0);

recv()本身是否提供任何防止缓冲区溢出的保护?例如,如果我将第三个参数更改recv()为高于所指向的缓冲区recv_data(例如 4000)的值 - 这会导致缓冲区溢出吗?(我实际上已经尝试过这样做,但似乎无法触发段错误)。

我实际上是在尝试创建一个故意易受攻击的服务器程序来更好地理解这些问题,这就是为什么我试图通过recv().

修正

并非不相关,将找出为什么上面会发送client.c超过. 我用来从标准输入填充该缓冲区,但如果我通过标准输入输入超过 1024 个字节,程序将显示它接收到所有字节!:)。for不限制发送的字节数吗?1024strlen(send_data)gets(send_data)server.cstrlen(send_data)send()

4

3 回答 3

10

例如,如果我将 recv() 的第三个参数更改为高于 recv_data 指向的缓冲区(例如 4000)的值 - 这会导致缓冲区溢出吗?

当然是的。如果网络缓冲区有 4000 字节的数据,则将其放入缓冲区。关键是,recv 像任何其他需要缓冲区的 C API 一样,它的长度认为调用者将传递缓冲区的实际长度,如果调用者传递了不正确的长度,那么错误在于调用者,它可能导致到未定义的行为。

在 C 中,当您将数组传递给函数时,被调用函数无法知道数组的大小。因此,所有 API 仅依赖于您提供的输入。

char recv_data[1024];

// Socket setup and so on ommited...

bytes_recieved = recv(connected, recv_data, 1024, 0);
recv_data[bytes_recieved] = '\0';

上面的代码可能会以多种方式引起麻烦。在以下情况下将导致未定义的行为:
(a) 如果 recv 返回-1,那么您直接索引到 recv_data 缓冲区而不检查返回值
(b) 如果 recv 返回1024,那么再次导致越界访问大小数组1024应该从0to访问1023

于 2013-03-03T15:46:52.667 回答
5

这个

recv_data[bytes_recieved] = '\0';

如果接收到 1024 个字节,可能会导致缓冲区溢出。

你可能想改变这个

bytes_recieved = recv(connected, recv_data, 1024, 0);

成为

bytes_recieved = recv(connected, recv_data, 1024 - 1, 0);

所以它bytes_recieved永远不会大于 1023,这是recv_data.


您的系统调用 ( recv()/ send()) 也缺少错误检查。-1在以任何其他方式使用结果之前测试它们是否已返回。


参考您的修改:

strlen()尝试返回从其参数指向的字符开始直到第一个NUL/字符的字符数0。此数字可以是任何值,具体取决于放置 terminating 的位置0

如果这个0-terminator 的 seach 在分配给strlen()s 参数的内存后面运行,程序肯定会遇到未定义的行为,因此可以返回任何值。

所以回答你的问题:如果send_data不是0终止strlen()会使应用程序运行到未定义的行为,因此它可能会崩溃或strlen()返回大于 1024 的值,因此send()会尝试发送此数量的字符。

于 2013-03-03T15:45:45.637 回答
0

即使您发送比recv()缓冲区更大的字节,您仍然可以recv()在成功调用时发送它recv(),这就是为什么您说它bytes_received仍然是5000字节,因为假设您发送5000字节,而您的接收缓冲区是1000字节,在第一次调用时recv()它只会1000在下一次调用时1000再次获取字节,直到它接收到您的所有数据。所以,我认为这里没有缓冲区溢出。这就是 TCP 的工作方式。

于 2013-03-03T16:04:38.267 回答