在对方接受请求之前防止写入套接字
我正在 Linux 中实现类似 FTP 的协议(家庭作业),我遇到了以下问题:客户端可能能够在另一方设法执行 accept() 之前(但在它监听之后)进行 connect() 和 write() ())。如何在不依赖于在不同的通信通道中传递“接受成功,您现在可以写入”等消息的情况下阻止写入操作工作?
I'm implementing an FTP like protocol in Linux (homework) and I came upon the following problem: the client may be able to connect() and write() before the other side managed to do accept() (but after it did listen()). How can I prevent the write operation from working without relying on passing messages like "accept succeeded, you can write now" in a different communication channel?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在建立 TCP 连接之前,connect() 调用不会返回。在服务器端调用accept()之前,数据不会到达服务器应用程序。然而,一旦建立 TCP 连接,客户端就可以开始发送数据。它将被服务器堆栈缓冲,直到被服务器应用程序读取。
阻止写操作的目的是什么?如果服务器延迟调用accept(),TCP窗口机制将暂停数据流。
The connect() call will not return until a TCP connection is established. Data won't reach the server app until the server side calls accept(). However, once the TCP connection is established the client may start sending data. It will be buffered by the server stack until it is read by the server app.
What is the purpose for preventing the write operation? The TCP window mechanism will pause data flow if the server is delayed in calling accept().
从次数上看TCP三向握手:
SYN
T1
发送T2
接收SYN-ACK
从服务器到客户端T3
的服务器发送T4
收到ACK
从客户端到服务器T5
发送T6
接收客户端上的阻塞
connect(2)
在T5< 返回/code>,而阻塞
accept(2)
在T6
返回,并且T5
严格小于T6
。所以是的,这是客户端可以开始发送数据认为连接已建立的时间窗口。如果客户端的ACK
丢失,服务器将陷入accept(2)
状态。这类似于著名的阻塞select(2)
/accept(2)
组合的竞赛。在
accept(2)
在服务器上返回之前,如果服务器不发送任何内容,您无法真正阻止客户端发送。解决这个问题的方法是使服务器套接字非阻塞并依赖
select(2)
/poll(2)/<代码>epoll(4)。
Look at the TCP three-way handshake in terms of times:
SYN
from client to serverT1
T2
SYN-ACK
from server to clientT3
T4
ACK
from client to serverT5
T6
Blocking
connect(2)
on the client returns atT5
, while blockingaccept(2)
returns atT6
, andT5
is strictly less thenT6
. So yes, that's the time window where client can start sending data thinking the connection is established. If client'sACK
is lost the server is stuck inaccept(2)
. This is similar to well-known race with blockingselect(2)
/accept(2)
combination.You can't really prevent the client from sending before
accept(2)
returns on the server without server sending something.A way around this is making the server socket non-blocking and relying on
select(2)
/poll(2)
/epoll(4)
.