客户端如何在用C编写的TCP服务器上故意触发accept错误?

客户端如何在用C编写的TCP服务器上故意触发accept错误?,c,sockets,tcp,server,C,Sockets,Tcp,Server,考虑以下用C编写的TCP服务器实现: 客户端中的结构sockaddr\u; int server_fd=socket(AF_INET,SOCK_STREAM,0); //绑定、侦听、错误处理等。 而(1){ int client_fd=accept(server_fd, (结构sockaddr*)和客户端, &客户(本地);; 如果(客户端\u fd

考虑以下用C编写的TCP服务器实现:

客户端中的结构sockaddr\u; int server_fd=socket(AF_INET,SOCK_STREAM,0); //绑定、侦听、错误处理等。 而(1){ int client_fd=accept(server_fd, (结构sockaddr*)和客户端, &客户(本地);; 如果(客户端\u fd<0){ 出口(1); } //对客户做些什么 关闭(客户_fd); } 客户端是否可能通过发送数据包故意使该服务器崩溃,从而导致
accept
调用失败(返回的值小于零)

手册页(Debian 10)列出了如下错误,但我不确定客户端是否能够触发其中任何错误:

  • 此外,可能会返回新套接字和协议定义的网络错误。 各种Linux内核可以返回其他错误,如ENOSR、eSocktnosSupport、eProtonosSupport、, 艾蒂迈德。在跟踪过程中可以看到值ERESTARTSYS

  • EPROTO协议错误

我已经尝试了几个相当简单的方法,比如立即断开客户端套接字。我解决这个问题的下一步是手工制作一些数据包,使用原始套接字或类似的工具,然后试图找到触发协议错误的方法


我找不到关于这方面的任何信息,所以我的问题是,是否有可能故意这样做,或者我是否可以停止尝试。

有许多方法使
accept()
失败,而且它们在操作系统和套接字实现中没有完全标准化


仅仅因为一个
accept()
调用失败而终止服务器不是一个好主意。最好记录错误并等待下一个传入连接。在您给出的示例中,少数错误(如
EINVAL
EFAULT
ENOTSOCK
)可能被认为是不可恢复的,因此如果服务器出现其中一个错误,您可以退出服务器,但应在应用程序堆栈的更大上下文中仔细考虑(例如,如果有一个看门狗将自动重新启动服务器)。

您所说的“使服务器崩溃”是什么意思?如果
accept()
失败,看起来您是故意终止它。
accept()
可能会失败,它将返回文档中描述的许多错误代码。@Havenard我的问题是,连接到服务器的人是否能够故意触发accept失败(如果是,如何触发)或者如果手册页中列出的错误仅仅是服务器错误。如果您无法完成TCP握手,我想是的。在大多数情况下,您应该询问您的操作系统,因为它提供了通信堆栈。@Havenard如果握手没有完成,则永远不会创建连接,永远不会进入待办事项队列,也永远不会得到任何数据。
accept()
。在超时之前,它一直在前面的队列中。谢谢你的回答,但这并不能回答我的问题。这是我看到有人在uni中为一个简单的服务器应用程序编写的一段代码。我想证明恶意客户端确实可以利用它进行攻击。@AlexR:这应该很简单:只需同时从10k或50k个客户端连接即可d获取
EMFILE
。当然,除非操作系统配置了一个巨大的
ulimit-n
。此外,请阅读Linux源代码,尝试找出导致
ECONNABORTED
的确切原因-这听起来很有希望。