面试题,socket进行send操作始终send不出去该怎么办?

杨白开水 2012-08-01 11:29:22
我的回答是,在应用层弄一个缓冲区,先把数据放入这个缓冲区,再从这个缓冲区写入socket。每次当socket可写时就从这个缓冲区里取走并发出,如果应用层的缓冲区满了就设置一个定时器,比如一分钟,如果定时器超时后应用层缓冲区还是满的,就断开链接。

感觉我的回答对方并不满意,而且好多次都被这么问到,请问各位大牛,有更好的解决办法么?
...全文
457 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
杨白开水 2012-08-02
  • 打赏
  • 举报
回复
嗯,非常感谢你的回答,我基本上懂了。
状态机那块以前看过vimer写的一个开源网络框架bayonet,比较的复杂,基本原理和你说的差不多。

我的经验比较少,非常感谢你的指导
qq120848369 2012-08-02
  • 打赏
  • 举报
回复
是啊, 我再读一遍发现你就这个意思.

再多的灵活设计, 比如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是否允许继续堆积,如果是则设置处理请求状态,递归调用状态机处理。

经验很重要,多看点开源服务器实现,多写点代码就懂了。
杨白开水 2012-08-01
  • 打赏
  • 举报
回复
那感觉你说的方法和我上面提到的方案没啥差别啊
qq120848369 2012-08-01
  • 打赏
  • 举报
回复
当然是上层了, 一个connection对应一个。

说句实话,这是LINUX网络开发基础功,这个都不会,进公司啥也干不了,完全没夸大。
杨白开水 2012-08-01
  • 打赏
  • 举报
回复
呃,你所说的这个buffer是socket自己的那个buffer还是你在上层自己定义的buffer呢
qq120848369 2012-08-01
  • 打赏
  • 举报
回复
epoll/select/poll,注册write事件,未写出数据追加到缓冲buffer,待write事件触发后继续尝试写出,直到buffer里内容全部写出则取消write事件。

如果注册有write事件(即buffer非空),此时希望发送的数据直接追加到buffer,以保证数据顺序写出。

如果buffer堆积到达一定长度,则认为网络状况不好,直接断开并清理此连接。

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧