Chinaunix

标题: close Socket 时发送tcp RST 信令而非FIN,怎么清空SOCKET读缓冲区? [打印本页]

作者: XZisonsun    时间: 2013-08-22 11:41
标题: close Socket 时发送tcp RST 信令而非FIN,怎么清空SOCKET读缓冲区?
本人在做web服务器的文件上传功能。我先解析IE发过来的头,发现上传的文件内容太大,于是我就不接受此次上传。我就close此socket,但由于此socket,读缓冲区还有数据,导致close操作 发送给IE一个rst信令而非fin。IE网页采用POST上传的、这样就会出现空白页面。

要解决这个问题 办法 1 是 发现文件太大了 仍然socket 接收,但不写入磁盘。 但这样太慢了。
                    2 发现文件太大。shutdown 关闭socket 读缓冲区,清楚读缓冲区, 再关闭写缓冲期
                       但 怎么清空读缓冲区呢?????????????

                     3  大家有没有好的处理办法?



作者: XZisonsun    时间: 2013-08-22 12:06
sf and up
作者: yulihua49    时间: 2013-08-22 12:16
XZisonsun 发表于 2013-08-22 11:41
本人在做web服务器的文件上传功能。我先解析IE发过来的头,发现上传的文件内容太大,于是我就不接受此次上传 ...

linger......................
作者: csumck    时间: 2013-08-22 12:46
回复 3# yulihua49


    mark,楼上说的详细点呢,把linger设置成多少?
作者: XZisonsun    时间: 2013-08-22 13:36
回复 3# yulihua49


    那个是针对发送吧?

我这个是接收。。。
作者: myworkstation    时间: 2013-08-22 14:33
回复 1# XZisonsun


    先shutdown(SHUT_RDWR或者SHUT_RD)然后再close,试试。shutdown之后对端不能再发送数据,但不影响既到达的数据缓冲。然后close,关闭连接。这样应该不会再rst。
作者: yxw-yxw    时间: 2013-08-22 17:02
本帖最后由 yxw-yxw 于 2013-08-22 17:03 编辑

ie 出现空白页面是因为你没有往 IE 发送数据就close了。

要达到你的要求,可以在检查到文件太大的时候(分析 http 头后),不用read(或是recv),直接往连接socket write(或是send)数据(错误消息之类的),然后close socket。close掉连接socket后,内核不再保留与之关联的缓冲区
作者: Aquester    时间: 2013-08-23 21:59
XZisonsun 发表于 2013-08-22 11:41
本人在做web服务器的文件上传功能。我先解析IE发过来的头,发现上传的文件内容太大,于是我就不接受此次上传 ...


close()正常需要执行四次握手,它不会发RST,而是FIN,只有之前发的数据已经被收到,peer才会收到FIN。
作者: cxytz01    时间: 2013-08-24 02:13
Aquester 发表于 2013-08-23 21:59
close()正常需要执行四次握手,它不会发RST,而是FIN,只有之前发的数据已经被收到,peer才会收到FIN。


对,close需要四次握手,并且会发送fin。 不会发送rst。


------------------------------
linger是针对发送的,不是针对接收的。

rst的发送条件有几样
1.客户端向服务器不存在的端口发送请求,会收到服务器的icmp不可达消息,tcp使用rst复位。
2.正常终止连接的方式是发送fin,但是可以设置lingger,来使用发送rst异常终止一个连接。
3.用于半打开链接。


作者: myworkstation    时间: 2013-08-24 15:36
回复 8# Aquester


    close的行为典型的情况下受linger选项的影响,针对linger的设置来讲,当其l_onoff非0,且l_linger为0,那么当套接口关闭时TCP将丢弃保留的套接口发送缓冲区的任何数据并发送一个 RST给对方。另一方面TCP的规范RFC 2525第2.17节规定了“如果缓存区有未读数据那么关闭socket将会发送RST给对放方“,linux实现符合些标准了,所以楼主情况是合理的。


RFC中的原话如下:
When an application closes a connection in such a way that it can
      no longer read any received data, the TCP SHOULD, per section
      4.2.2.13 of RFC 1122, send a RST if there is any unread received
      data, or if any new data is received. A TCP that fails to do so
      exhibits "Failure to RST on close with data pending".


linger发送RST的行为在man文档中有比较隐晦的说明:
If SO_LINGER is disabled and a close is issued, the sys-
     tem will process the close in a manner that allows the process to con-
     tinue as quickly as possible
作者: myworkstation    时间: 2013-08-24 15:37
回复 9# cxytz01


    你的解释不完全对,详细解释看回复
作者: cxytz01    时间: 2013-08-25 20:23
回复 11# myworkstation

哪里有错,看不出来,请指正。我是根据unp, tcp/ip详解卷一来的,里面是这么说的。


   
作者: myworkstation    时间: 2013-08-25 20:35
回复 12# cxytz01


    close需要四次握手,并且会发送fin。 不会发送rst。
这句话有问题,你下面明明已经说了“正常终止连接的方式是发送fin,但是可以设置lingger,来使用发送rst异常终止一个连接。”,
而且我在之前的回贴中也说了。TCP的规范RFC 2525第2.17节规定了“如果缓存区有未读数据那么关闭socket将会发送RST给对放方“,所以这时候既使不设置linger,close也同样会发送rst

作者: bo8362    时间: 2015-12-28 16:25
版主就是版主,水平高呵




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2