gaojl0728 发表于 2014-04-02 17:25

回复 19# seufy88


一般用TCP编程在应用层都会设计自己的协议来保证对端最后一个包已经发完才会调close, 要不然就RST了。
这一点需要应用层自己保证, 内核不管。

gaojl0728 发表于 2014-04-02 17:26

回复 20# seufy88


    这个就有点复杂了, 不太容易理清楚这个过程,不确定啊。

seufy88 发表于 2014-04-02 17:40

gaojl0728 发表于 2014-04-02 17:25 static/image/common/back.gif
回复 19# seufy88




所以这也是大家推荐的不要“暴力”close,而应该更优雅的方式关闭socket了。
比如
主动关闭方先调用shutdown (W)
过一段时间后read返回0(对方也发FIN了)后再调用close,真正关闭。

不知道实际生产中是如何做的(本人没写过网络程序:oops: )

seufy88 发表于 2014-04-02 19:30

回复 10# timespace


    理论上讲,对方不发FIN,那么local侧处在FIN_WAIT_2,对方处在CLOSE_WAIT,这么一样保持这样下去.
直到应用层决定进行关闭.

但是在berkely版本中,会防止永远在FIN_WAIT_2无限等待下去.而是会设置一个TIMER,到点了就会进入CLOSE状态.
但这个实现本身是违背TCP协议的.

timespace 发表于 2014-04-02 20:23

回复 24# seufy88
貌似主流系统都支持这个超时,否则一直等下去不是办法,RFC有提到不能设超时吗?


   

linux_c_py_php 发表于 2014-04-03 10:08

握手是4次单向通讯完成的, shutdown WR只是第一步而已。

seufy88 发表于 2014-04-03 22:12

本帖最后由 seufy88 于 2014-04-03 22:18 编辑

linux_c_py_php 发表于 2014-04-03 10:08 static/image/common/back.gif
握手是4次单向通讯完成的, shutdown WR只是第一步而已。

正好想请教你.
我们平常所说的server并发处理,这里所谓的并发处理client侧来的连接请求.
以nginx来说,其实就是epoll同时监听多个socket,如果有需要处理的socket,就还是"循环"依次处理各个"有效"的socket.
如此一来,如果每个处理过程花费的时间相对级别上很多的话,这个"并发处理"是不是感觉就不像是并发处理了,因为process就这么一个,
epoll_wait后还是要依序处理各个socket的

刚开始接触时,一直没明白nginx这样单process,不使用线程(出于开稍原因),单process处理几W并发,所谓的并发是什么回事.

能不能说说nginx的非阻塞异步,为什么被称为是并发处理?
因为讲给初学者"并发",脑子里第一反应就是"fork多process,或是以多线程的方式1对1处理client请求"
看完nginx单process模型后,还是有点疑问,怎么epoll多路后就成了所谓的并发了,不也还是一个一个请求依次执行的嘛(站在只有一个process的角度)

本人没写过服务器程序,理解或有偏差请见谅

seufy88 发表于 2014-04-05 09:10

本帖最后由 seufy88 于 2014-04-05 09:14 编辑

回复 21# gaojl0728

一般用TCP编程在应用层都会设计自己的协议来保证对端最后一个包已经发完才会调close, 要不然就RST了。
这一点需要应用层自己保证, 内核不管。
==>local侧只需要保证队列里没有要read的数据就可以调用close,发送FIN了吧.
因为如果应用层要保证对对端最后一个包已经发完,那只能read返回 0(对端主动FIN),此情况下local再close,岂不是一直是被动FIN?


完整的过程是本端调用close发送FIN给对方, 此时本端进入FIN_WAIT_1,
如果此时对端发过来不带ACK的包(包括纯FIN包和纯数据包),直接丢掉, 如果是带ACK的数据包, 本端会进入FIN_WAIT_2, 同时这个数据包也会进入TCP队列, 此后如果来的还是带ACK的数据包, 数据包还能进入TCP队列。
直到FIN+ACK为止, 其他包都丢掉了。
===>我想问一下,本端调用close发送FIN时,有没有可能本端之前还有未被ack的数据存在?即TCP协议中,是否一定要所有发出的数据被ack后才能FIN?
关于这一点,书中并没有提到.据我所知,最后一个数据包可以一并带上FIN的标示.
这里我想带出另一个问题,应用层调用send返回后,数据是交由内核发送了,但实际上,应该没有被ACK吧?




   

winshining 发表于 2014-04-12 15:12

回复 27# seufy88


    nginx会开子进程处理的吧,很久以前看过nginx的父子进程通信的代码,分为master和worker的,其实就是父进程和子进程,worker的个数还可以配置的。

seufy88 发表于 2014-04-13 09:43

回复 29# winshining

我说的(并发)就是子进程的事.没关父进程什么事.

   
页: 1 2 [3] 4
查看完整版本: socket中close和shutdown的区别