jvf*_*jvf 3 sockets erlang network-programming tcp gen-tcp
使用半连接的连接,我的意思是客户端的调用connect()成功返回的连接,但服务器调用accept()没有.这可以通过以下方式发生:客户端调用connect(),从而生成SYN到服务器的数据包.服务器进入状态SYN-RECEIVED并向SYN-ACK客户端发送数据包.这会导致客户端回复ACK,进入状态ESTABLISHED并从connect()呼叫返回.如果最终ACK丢失(或忽略,由于在服务器上,这可能是更可能的情况全接受队列),服务器仍处于状态SYN-RECEIVED和accept()不返回.由于与SYN-RECEIVED状态相关的超时SYN-ACK将重新发送,允许客户端重新发送ACK.如果服务器能够ACK最终处理,它也将进入状态ESTABLISHED.否则它最终将重置连接(即发送RST到客户端).
您可以通过在单个侦听套接字上启动大量连接来创建此方案(如果不调整积压工作tcp_max_syn_backlog).有关更多详细信息,请参阅此问题和本文.
我进行了几次实验(使用此代码的变体)并观察了一些我无法解释的行为.所有使用Erlang gen_tcp和当前Linux 执行的实验,但我强烈怀疑答案并非特定于此设置,所以我试图在这里保持更一般.
connect()- >等 - > send()- >receive()我的出发点是从客户端建立连接,等待1到5秒,向服务器发送"Ping"消息并等待回复.通过这种设置,我观察到当我有一个半连接时receive()失败并出现错误closed.在send()半连接的连接期间从未出现过错误.您可以在此处找到有关此设置的更详细说明.
connect() - >漫长的等待 - > send()要看,如果我在半连接的连接上发送数据时可能会出错,我会在发送数据前等待4分钟.4分钟应涵盖与半连接相关的所有超时和重试.仍然可以发送数据,即send()无错误地返回.
connect() - > receive()接下来我测试了如果我只receive()用非常长的超时(5分钟)调用会发生什么.我的期望是closed在半成熟的连接中得到错误,就像在原始实验中一样.唉,没有任何事情发生,没有错误被抛出,接收最终超时.
send()半连接成功?receive()如果我先发送数据,为什么只会失败?任何帮助,特别是详细解释的链接,都是受欢迎的.
从客户端的角度来看,会话完全建立,它发送SYN,返回SYN/ACK并发送ACK.只有在服务器端,您才有半成熟的状态.(即使它从服务器获得重复的SYN/ACK,它也会重新确认,因为它处于已建立的状态.)
的send,因为只要客户而言,建立会话本届会议工作正常.发送数据不需要被远端确认才能成功(当数据被复制到内核缓冲区时发送系统调用完成),但见下文.
我在这里相信发送实际上是在连接上产生错误(可能是RST),因为接收系统无法在尚未完成建立的会话上确认数据.我的猜测是,在发送加上短暂延迟(即当RST有机会返回)时发生的任何引用客户端套接字的系统调用都将导致错误.
接收本身永远不会导致错误,因为客户端不需要为接收做任何事情(我的意思是TCP协议); 它只是在等待.但是一旦你发送了一些数据,你就迫使服务器方面了:它已经完成了会话建立(在这种情况下它可以接受数据),或者它必须发送一个重置(我猜这里它不能"持有" "未完全建立的会话上未传递的数据".
| 归档时间: |
|
| 查看次数: |
871 次 |
| 最近记录: |