日期:2014-05-16  浏览次数:20895 次

面试题,socket进行send操作始终send不出去该怎么办?
我的回答是,在应用层弄一个缓冲区,先把数据放入这个缓冲区,再从这个缓冲区写入socket。每次当socket可写时就从这个缓冲区里取走并发出,如果应用层的缓冲区满了就设置一个定时器,比如一分钟,如果定时器超时后应用层缓冲区还是满的,就断开链接。

感觉我的回答对方并不满意,而且好多次都被这么问到,请问各位大牛,有更好的解决办法么?

------解决方案--------------------
是啊, 我再读一遍发现你就这个意思.

再多的灵活设计, 比如Buffer堆积过多就暂时不处理请求(取消读事件或者忽略之), 这样可以避免请求堆积造成应答Buffer不停的增长.

具体点, 比如绝大多数Web服务器基于状态机实现, 一个典型的场景比如:

5个请求一次性读入req buffer, 此前状态为等待请求状态, 基于状态机的服务器实现一般将5个请求一次性解析出来放入req list,随之进入处理请求状态, 状态机从req list取得一个req处理并response, 检查仍有剩余req则递归进入请求处理状态, 继续获取一个req, 如此递归直到req list取空则进入等待请求状态。 中间任何一个req的response堆积res buffer过长都可以保持req仍留存在list中并保证注册write事件(可能之前已经因未写出注册过)从而进入停止请求状态。 在今后write事件触发后,检查到如果是停止请求状态(如前一个括号所说,可能不在此状态),那么除了将堆积buffer写出外,还需检查堆积buffer是否允许继续堆积,如果是则设置处理请求状态,递归调用状态机处理。

经验很重要,多看点开源服务器实现,多写点代码就懂了。