大并发服务器必备技术:tcp cork

如果把tcp当成服务端与客户端的管道,cork 就是给管道加个塞子。

为什么 要加个塞子呢 ?

先来举个例子:

int times = 10;
while( times--)
{
     send( sock_fd, buf,  1, 0 )
}

这段program会发送数据10次,每次就发送1个字节,这样会不会什么问题呢?

记得 以前农忙的时候,田里的稻子收割完了,要打成稻谷,就放一个打稻机子,父亲在机子旁打稻,而我则 负责抱起稻子送给他。父亲打稻的速度很快,很小的时候我每次只抱一捆稻子,就会不停 地奔跑,很 忙很累。。。等我稍大一点,能一次抱几捆的时候绝不会只抱一捆,这个道理是不是很浅显。

话说回来,如果发送数据的包很小,而次数又很多,网络也会很累,这个累也有学名的,叫网络拥塞。

我们需要将稻子收集多一点再送,意思就是将网络包整大一点,怎么做到 呢?

当包很 小的时候先停一停,等到 一定的数量的包产生了再一起发,是不是有点像给水流管道加个塞子塞住, 等水够多的时候才放出,其实我觉得更像一个水闸,什么时候放水由闸门开关决定。

上面的代 码稍改一下:

1 int times = 10;
2 int on = 1;
3 setsockopt ( sock_fd, SOL_TCP, TCP_CORK, &on, sizeof (on));
4 while( times--)
5 {
6    send( sock_fd, buf,  1, 0 )
7 }
8 on = 0;
9 setsockopt ( sock_fd, SOL_TCP, TCP_CORK, &on, sizeof (on));

2-3行相当于塞上 塞子(关掉闸门),4-7行相当于收集更多的水,8-9行相当于拨去塞子(打开闸门),这样就解决了网 络拥塞的问题。

后面的学习我们会发现第9行其实有时候可以省掉。

查看本栏目更多精彩内容:http://www.bianceng.cn/Servers/zs/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索网络
, times
管道
cork 爱尔兰、cock、corkscrew、cork港口、cork鞋,以便于您获取更多的相关知识。

时间: 2024-10-28 08:23:18

大并发服务器必备技术:tcp cork的相关文章

大并发服务器必备技术:sendfile

socket发送函数. int send( SOCKET s, const char FAR *buf, int len, int flags ); 如果内容是动态生成的,一般是把传输内容直接丢给buf中用send函数传输,没有优化的空 间. 文件传输则要先把内容read到buf中,因此至少两次内核调用,如果文件很大,可能会用一 个循环调用,如: while( size == PER_SIZE ) { size = read( fd, buf, PER_SIZE ); if( size >0 )

大并发服务器必备技术:connect 异步

前面我们谈的大多是服务端与客户端的技术,服务器开发其实有时还会涉及到跨服务器的访问,比 如腾讯的拍拍服务器需要知道登录的会员信息,就需要访问会员服务器. 跨务器访问会涉及到 很多的技术,比如访问权限控制,数据同步等,这里主要来学习一下传输层. 为了更容易理解 ,我们将访问端服务器称为客户端,被访问端服务器称为服务端. 客户端发起一个连接的过程 : socket_fd = socket( AF_INET,SOCK_STREAM,0 ); ret = connect( socket_fd, (soc

大并发服务器必备技术:http 缓存

前面所说技术订都是服务器端一个人在努力,有时候也需要客户端配合. 一个链接请求过程 大致可以分成几个阶段 如果客户端发送同样的 请求,且结果都一样,我们是不是可以缓冲一下呢?是不是可以减少几步呢? 的确可以,一般来 说以下几种方法: 1.我们先试着在服务端进行缓冲,我们试着将一个已经返回的长链接发送内 容不作释放,下次请求时直接返回刚才发送的内容,这个不适用于频繁访问,适用于一些特殊的情况, 特殊的请求. 2.对于静态的文件都有上次修改时间lastupdatetime,客户端第一次请求返回的 h

大并发服务器必备技术:writev

前面我们说过,对于静态文件的传输,用sendfile可以减少系统调用,现在我们看看动态的数据应 该如何处理. 首先,如果数据足够小(小于1024)且只有唯一的一个buffer,我们直接用 send/write 就可以了. 通常的情况下,程序可能会在多个地方产生不同的buffer,如 nginx, 第一个phase里都可能会产生buffer,放进一个chain里, 如果对每个buffer调用一次send,系 统调用的个数将直接等于buffer的个数,对于多buffer的情况会很糟. 可能大家会想到

大并发服务器内存转换的灵活运用,memcpy的思考

在很多的网络开发中,经常会碰到一些内存转换,如下面的场景: #define PACKAGE_PARSE_ERROR -1 #define PACKAGE_PARSE_OK 0 int parse_package( int* a, int* b, int* c, int* d, char* buf, int buf_len ) { if( !buf || buf_len < 16 ){ return PACKAGE_PARSE_ERROR; } memcpy( a, buf, 4 ); memcp

搭建一个后台服务器:服务端(异步,大并发)

上篇的阻塞模式下服务器的并发只有几K,而真正的server 像nginx, apache, yumeiz 轻轻松松处 理几万个并发完全不在话下,因此大并发的场合下是不能用阻塞的. 1W的并发是一个分隔点,如果单进程模型下能达到 的话,说明至少在服务器这块你已经很厉害了. 服务器开发就像一门气功,能不能搞出大并发,容错性处理得怎么样,就是你有没有内功,内功有 多深. 异步模式是专门为大并发而生,linux下一般用 epoll 来管理事件,下面就开始我们的异步大并发 服务器实战吧. 跟阻塞开发一样,

高并发服务器的设计之架构与瓶颈的设计

做架构设计,难免有时候被人问及系统的瓶颈在哪,那首先来了解下什么是瓶颈? 打个形象 的比方,人的嘴巴可以吞下一整个面包,但是却咽不下去,因为食管不给力,它比较细,所以嘴巴能吞 下的食物大小要受到食管的粗细限制. 城市内部每天会产生几十万件跨城快递,可是跨城的交 通不给力,只允许走小型卡车,一卡车一次就能装几千件,一天下来也不一定能投送的完. 人 在一定时间内能咽下多少食物,货运公司在一天运送多少货物,物理上叫做吞吐量,系统整体的吞吐量 等于最小区域的吞吐量. 下面这张图能够反映: 土黄色管子的流

《UNIX网络编程 卷1:套接字联网API(第3版)》——2.10 TCP端口号与并发服务器

2.10 TCP端口号与并发服务器 并发服务器中主服务器循环通过派生一个子进程来处理每个新的连接.如果一个子进程继续使用服务器众所周知的端口来服务一个长时间的请求,那将发生什么?让我们来看一个典型的序列.首先,在主机freebsd上启动服务器,该主机是多宿的,其IP地址为12.106.32.254和192.168.42.1.服务器在它的众所周知的端口(本例为21)上执行被动打开,从而开始等待客户的请求,如图2-11所示. 我们使用记号{:21, :}指出服务器的套接字对.服务器在任意本地接口(第

UNIX网络编程:并发服务器(TCP)

在迭代服务器中,服务器只能处理一个客户端的请求,如何同时服务多个客户端呢?在未讲到select/poll/epoll等高级IO之前,比较老土的办法是使用fork来实现. 网络服务器通常用fork来同时服务多个客户端,父进程专门负责监听端口,每次accept一个新的客户端连接就fork出一个子进程专门服务这个客户端.但是子进程退出时会产生僵尸进程,父进程要注意处理SIGCHLD信号和调用wait清理僵尸进程,最简单的办法就是直接忽略SIGCHLD信号. 当一个连接建立时,accept返回,服务器接