S*A 发帖数: 7142 | 1 这个练习1 已经发现了,C10M 没有强壮的内存支持是
没戏的。单单是 kernel 部分就已经消耗很多内存了。
所以我们把目标调整一下,1M per 4G RAM。
这样 64G 内存就有可能实现 10M。
练习2 就是看看,我们如果保留 1M/4G 的空TCP
连接,可不可以。完全不往 TCP 里面发东西。就是
建立连接而已。这样也不存在 epoll 问题。
和实验1一样,我会发些拍脑瓜想出来的简单代码。
你直接用这个代码冲刺 1M/4G 会碰到些实际问题。
有兴趣的同学跟着做一下实验,看看有没有办法解
决这些问题。
BTW,我是实验出了 1M/4G (服务器方),所以是
有可能的。建立1M 连接还花了不少时间。
服务器方代码。端口是80, 大家可以自己改。
include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void die(char *reason)
{
perror(reason);
exit(1);
}
int main(int argc, char *argv[])
{
int listen_sock, conn_sock;
struct sockaddr_in raddr, localaddr = {
.sin_family = PF_INET,
.sin_port = ntohs(80),
.sin_addr.s_addr = INADDR_ANY
};
int ret;
socklen_t addrlen = sizeof(raddr);
int lisnum = 10;
struct rlimit r;
int i;
int yes = 1;
listen_sock = socket(PF_INET, SOCK_STREAM, 0);
if (listen_sock < 0)
die("socket");
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
ret = bind(listen_sock, (struct sockaddr *) &localaddr, sizeof(struct
sockaddr));
if (ret < 0)
die("bind");
ret = listen(listen_sock, lisnum);
if (ret < 0)
die("listen");
for (i = 0; i < 1000000; i++) {
conn_sock = accept(listen_sock,
(struct sockaddr *)
&localaddr, &addrlen);
if (conn_sock < 0)
die("accept");
if ((i%10000) == 0 || i < 10)
printf("%dn", i);
}
return 0;
} |
S*A 发帖数: 7142 | 2 拍脑瓜的简单客户端。假设端口是 80, 启动指定服务器 IP 地址,
不用域名。当然会碰到一个 IP 地址只能发出去 65K 个连接的限制。
如何用 ip alias 使用多个 IP 地址解决这个问题留给大家自己改。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void die(char *reason)
{
perror(reason);
exit(1);
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr, localaddr;
int i,j, ret;
int total = 0;
if (argc != 2)
die("usage: a.out ");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(80);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
die("inet_pton error for arg1");
for (i=1; i < 1000000; i++) {
int so_reuseaddr = 1;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
die("socket error");
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR, &so_reuseaddr, sizeof
so_reuseaddr);
if (connect(sockfd, (struct sockaddr *) & servaddr, sizeof(
servaddr)) < 0)
die("connect error");
printf("%d\n",++total);
}
} |
b*******s 发帖数: 5216 | 3 迟一点试试看
就不用给伪币了
挺有趣的
【在 S*A 的大作中提到】 : 这个练习1 已经发现了,C10M 没有强壮的内存支持是 : 没戏的。单单是 kernel 部分就已经消耗很多内存了。 : 所以我们把目标调整一下,1M per 4G RAM。 : 这样 64G 内存就有可能实现 10M。 : 练习2 就是看看,我们如果保留 1M/4G 的空TCP : 连接,可不可以。完全不往 TCP 里面发东西。就是 : 建立连接而已。这样也不存在 epoll 问题。 : 和实验1一样,我会发些拍脑瓜想出来的简单代码。 : 你直接用这个代码冲刺 1M/4G 会碰到些实际问题。 : 有兴趣的同学跟着做一下实验,看看有没有办法解
|
d*******r 发帖数: 3299 | |
c****3 发帖数: 10787 | 5 要设SO_SNDBUF和SO_RCVBUF,否则光这两个socket buffer在Linux里的默认值,就吃掉
大量内存
【在 S*A 的大作中提到】 : 这个练习1 已经发现了,C10M 没有强壮的内存支持是 : 没戏的。单单是 kernel 部分就已经消耗很多内存了。 : 所以我们把目标调整一下,1M per 4G RAM。 : 这样 64G 内存就有可能实现 10M。 : 练习2 就是看看,我们如果保留 1M/4G 的空TCP : 连接,可不可以。完全不往 TCP 里面发东西。就是 : 建立连接而已。这样也不存在 epoll 问题。 : 和实验1一样,我会发些拍脑瓜想出来的简单代码。 : 你直接用这个代码冲刺 1M/4G 会碰到些实际问题。 : 有兴趣的同学跟着做一下实验,看看有没有办法解
|
S*A 发帖数: 7142 | 6 还没有开始发数据,好像我没有改也过了。
没准有真正数据才开始用 buffer?
你们会碰到其他险恶的问题的,哈哈哈。
【在 c****3 的大作中提到】 : 要设SO_SNDBUF和SO_RCVBUF,否则光这两个socket buffer在Linux里的默认值,就吃掉 : 大量内存
|
c****3 发帖数: 10787 | 7 不用发数据,这两个buffer是在TCP连接建立好之前设置的,建立之后就不能改了。对
应就TCP协议里的用于流控的TCP Windows size。
如果默认值是2K,发送接收4K,1M连接,光这两个buffer,就需要4G内存
【在 S*A 的大作中提到】 : 还没有开始发数据,好像我没有改也过了。 : 没准有真正数据才开始用 buffer? : 你们会碰到其他险恶的问题的,哈哈哈。
|
S*A 发帖数: 7142 | 8 我可以告诉你的是我的实验通过了,就是在4G 的笔记本上,
服务器端程序没有改。(其配置有改)。这个buffer 我的确
没有碰。你能指出 kernel allocate buffer 的代码在那里吗?
我们可以一起看看是不是空连接就已经分配 window buffer 了。
我粗略看了一下,没有在连接的时候找到。如果你很确定知道
buffer 在那里分配的,有 kernel 源程序最好。那值得研究一下
为什么我的机器没有 crash.
【在 c****3 的大作中提到】 : 不用发数据,这两个buffer是在TCP连接建立好之前设置的,建立之后就不能改了。对 : 应就TCP协议里的用于流控的TCP Windows size。 : 如果默认值是2K,发送接收4K,1M连接,光这两个buffer,就需要4G内存
|
b********e 发帖数: 595 | 9
ss -t -m试试,我印象平时是空的
另外学习别人的经验,装systemtap查。我觉得C1M问题离programming版有点远,不是
多少行代码的问题。
看链接:
http://blog.yufeng.info/archives/2511
【在 S*A 的大作中提到】 : 我可以告诉你的是我的实验通过了,就是在4G 的笔记本上, : 服务器端程序没有改。(其配置有改)。这个buffer 我的确 : 没有碰。你能指出 kernel allocate buffer 的代码在那里吗? : 我们可以一起看看是不是空连接就已经分配 window buffer 了。 : 我粗略看了一下,没有在连接的时候找到。如果你很确定知道 : buffer 在那里分配的,有 kernel 源程序最好。那值得研究一下 : 为什么我的机器没有 crash.
|
S*A 发帖数: 7142 | 10 这个问题我大概有理解了。那个tcp buffer 就是sk_buff 链。没有其它的另外buffer
,所以没有数据就是空的。
【在 b********e 的大作中提到】 : : ss -t -m试试,我印象平时是空的 : 另外学习别人的经验,装systemtap查。我觉得C1M问题离programming版有点远,不是 : 多少行代码的问题。 : 看链接: : http://blog.yufeng.info/archives/2511
|
|
|
b*******s 发帖数: 5216 | 11 昨天看了下内核的代码,新建socket就是分配了新的inode,以及你说的sk list,一个空
的双向链表,还有些structure
buffer
【在 S*A 的大作中提到】 : 这个问题我大概有理解了。那个tcp buffer 就是sk_buff 链。没有其它的另外buffer : ,所以没有数据就是空的。
|
S*A 发帖数: 7142 | 12 //hand
这个也是我的结论。那个 TCP buffer 就是在sk_buffer 链里面表示的。
【在 b*******s 的大作中提到】 : 昨天看了下内核的代码,新建socket就是分配了新的inode,以及你说的sk list,一个空 : 的双向链表,还有些structure : : buffer
|
b*******s 发帖数: 5216 | 13 http://www.linuxjournal.com/article/1312
在源代码里看到他的名字,搜了一下
【在 S*A 的大作中提到】 : //hand : 这个也是我的结论。那个 TCP buffer 就是在sk_buffer 链里面表示的。
|
b*******s 发帖数: 5216 | 14 昨天还干了件蠢事,直接给vm分了4g内存,想看看有什么区别
后来发现vm里centos是32位的
【在 S*A 的大作中提到】 : //hand : 这个也是我的结论。那个 TCP buffer 就是在sk_buffer 链里面表示的。
|
S*A 发帖数: 7142 | 15 2G/2G or 3G/1G split kernel 地址空间不够用?
【在 b*******s 的大作中提到】 : 昨天还干了件蠢事,直接给vm分了4g内存,想看看有什么区别 : 后来发现vm里centos是32位的
|
S*A 发帖数: 7142 | 16 提示一下,这个练习需要编写连接一个远程端口的时候,
使用指定的本定 IP 地址。如果让系统自动挑 IP, 系统
只会自动挑第一个满足 routing 条件的 IP,用光这个 IP
所有的端口就跑不下去了。
谁来试着改进一下程序使用指定的本地 IP? |
d*******r 发帖数: 3299 | 17 搞个 github 帐号吧,把大家的研究成果和步骤存上去 |
S*A 发帖数: 7142 | 18 我其实就是抛砖引玉而已,我大概不会把解决方案
直接贴上去,这样就没有了解决问题的乐趣。我说的
这些问题,分开拆解其实都不难对付。
github 大概会要有更加成熟的东西才会考虑贴。 |
l***e 发帖数: 450 | 19 not exactly,the so_snd and so_rcv only enforce the limit of buffer that can
be used/queued at the socket, it does not really commit any buffer space.
The buffer comes from network driver for inbound traffic, and application
for outbound traffic.
【在 c****3 的大作中提到】 : 不用发数据,这两个buffer是在TCP连接建立好之前设置的,建立之后就不能改了。对 : 应就TCP协议里的用于流控的TCP Windows size。 : 如果默认值是2K,发送接收4K,1M连接,光这两个buffer,就需要4G内存
|
c****3 发帖数: 10787 | 20 IP fragment重组是不能靠network driver的,没有buffer怎么做。
can
【在 l***e 的大作中提到】 : not exactly,the so_snd and so_rcv only enforce the limit of buffer that can : be used/queued at the socket, it does not really commit any buffer space. : The buffer comes from network driver for inbound traffic, and application : for outbound traffic.
|
|
|
S*A 发帖数: 7142 | 21 这个问题我和 brainless 在另外一个贴里面有比较深入的讨论了。
http://www.mitbbs.com/article_t1/Programming/31330685_0_7.html
这个在建立空的 TCP 连接的时候是不需要的。也就是说,现在
的 Linux 还是比较聪明的,不会在没有需要的时候把buffer 白白
预留在那里。
buffer 就是以 sk_buff 的形式存在的,是有数据进来的时候才
分配。IP fragment 就是用buffer的其中一部分,对网卡就是改
buffer地址和长度,没有什么难度。要把几个用户的send buffer
合并到一个 ip 包里面,依然可以用网卡驱动直接完成。现在网卡
有 scatter/gather list, 你可以把几个不同的buffer直接告诉网卡
用一个包发出去。只有特别老的网卡不支持 scatter/gather list.
我记得以前特别著名的 NE2000 就是那样,现在应该没有那种网卡
了。
【在 c****3 的大作中提到】 : IP fragment重组是不能靠network driver的,没有buffer怎么做。 : : can
|
b*******s 发帖数: 5216 | 22 最近我在考虑买台server做试验用,看看现在8个核,64g ram的机器也就两三千刀
和一个macbook pro开发本差不多贵
【在 S*A 的大作中提到】 : 这个问题我和 brainless 在另外一个贴里面有比较深入的讨论了。 : http://www.mitbbs.com/article_t1/Programming/31330685_0_7.html : 这个在建立空的 TCP 连接的时候是不需要的。也就是说,现在 : 的 Linux 还是比较聪明的,不会在没有需要的时候把buffer 白白 : 预留在那里。 : buffer 就是以 sk_buff 的形式存在的,是有数据进来的时候才 : 分配。IP fragment 就是用buffer的其中一部分,对网卡就是改 : buffer地址和长度,没有什么难度。要把几个用户的send buffer : 合并到一个 ip 包里面,依然可以用网卡驱动直接完成。现在网卡 : 有 scatter/gather list, 你可以把几个不同的buffer直接告诉网卡
|
S*A 发帖数: 7142 | 23 回到正题上,用 4G 内存的笔记本保持 1M 个空的 TCP 连接
我已经实验出来了。所以这一步定下的目标是可以是实现的,
大家不用过于担心 4G 不够用的问题,至少这一步不用。
还是需要在客户端改用指定的 IP 地址才能避免同一个 IP 有
65K 个端口的限制。现在我还没有看到有其他同学贴这个代码
出来。这样吧,我再放 10 个包子,给第一个贴用多个 IP 连
接的。就是简单的 socket 编程啊。
然后我再追加一个非常简单的要求,原来程序里面得到的连接
的 handle 是直接扔掉的。现在要求把得到的 handle 放到一个
大数组里面,1M TCP 就是 4M 空间,很小。然后这把柄的数
组就是下一步练习 3 epoll 要用到的。
大家加油啊。 |
j*a 发帖数: 14423 | 24 我觉得这个说得挺清楚的了:
http://stackoverflow.com/questions/1175108/
Use getifaddrs() to enumerate all the interfaces
and find the IP address for the interface you want
to bind to. Then use bind() to bind to that IP
address, before you call connect().
【在 S*A 的大作中提到】 : 回到正题上,用 4G 内存的笔记本保持 1M 个空的 TCP 连接 : 我已经实验出来了。所以这一步定下的目标是可以是实现的, : 大家不用过于担心 4G 不够用的问题,至少这一步不用。 : 还是需要在客户端改用指定的 IP 地址才能避免同一个 IP 有 : 65K 个端口的限制。现在我还没有看到有其他同学贴这个代码 : 出来。这样吧,我再放 10 个包子,给第一个贴用多个 IP 连 : 接的。就是简单的 socket 编程啊。 : 然后我再追加一个非常简单的要求,原来程序里面得到的连接 : 的 handle 是直接扔掉的。现在要求把得到的 handle 放到一个 : 大数组里面,1M TCP 就是 4M 空间,很小。然后这把柄的数
|
S*A 发帖数: 7142 | 25 代码,描述没有包子。
【在 j*a 的大作中提到】 : 我觉得这个说得挺清楚的了: : http://stackoverflow.com/questions/1175108/ : Use getifaddrs() to enumerate all the interfaces : and find the IP address for the interface you want : to bind to. Then use bind() to bind to that IP : address, before you call connect().
|
S*A 发帖数: 7142 | 26 这个说的对,我的实验也是这样干的。
只不过 interface 是我自己建立的,我不用去查看
什么 IP。查看也行,如果已经有程序建立了那 20
多个虚拟网卡。我不建议手动建立 20 个 ip alias.
等待代码。
【在 j*a 的大作中提到】 : 我觉得这个说得挺清楚的了: : http://stackoverflow.com/questions/1175108/ : Use getifaddrs() to enumerate all the interfaces : and find the IP address for the interface you want : to bind to. Then use bind() to bind to that IP : address, before you call connect().
|
S*A 发帖数: 7142 | 27 不要被我呼悠了啊,我可不保证你的 server 可以上 10M 连接啊.
如果你真的要买,搞个 Intel 的网卡,可以玩 DKDP。 看上去
DKDP 比 OpenOnLoad 可玩性高。实用不一定啊。
建议还是先用的现有的机器把实验做了,把低端机器推到极致。
确定是内存限制了你的性能,然后再上高端的机器。
【在 b*******s 的大作中提到】 : 最近我在考虑买台server做试验用,看看现在8个核,64g ram的机器也就两三千刀 : 和一个macbook pro开发本差不多贵
|
b*******s 发帖数: 5216 | 28 不光是做这个试验,反正也没几个钱,还能捣鼓点别的东西
【在 S*A 的大作中提到】 : 不要被我呼悠了啊,我可不保证你的 server 可以上 10M 连接啊. : 如果你真的要买,搞个 Intel 的网卡,可以玩 DKDP。 看上去 : DKDP 比 OpenOnLoad 可玩性高。实用不一定啊。 : 建议还是先用的现有的机器把实验做了,把低端机器推到极致。 : 确定是内存限制了你的性能,然后再上高端的机器。
|
S*A 发帖数: 7142 | 29 这个练习1 已经发现了,C10M 没有强壮的内存支持是
没戏的。单单是 kernel 部分就已经消耗很多内存了。
所以我们把目标调整一下,1M per 4G RAM。
这样 64G 内存就有可能实现 10M。
练习2 就是看看,我们如果保留 1M/4G 的空TCP
连接,可不可以。完全不往 TCP 里面发东西。就是
建立连接而已。这样也不存在 epoll 问题。
和实验1一样,我会发些拍脑瓜想出来的简单代码。
你直接用这个代码冲刺 1M/4G 会碰到些实际问题。
有兴趣的同学跟着做一下实验,看看有没有办法解
决这些问题。
BTW,我是实验出了 1M/4G (服务器方),所以是
有可能的。建立1M 连接还花了不少时间。
服务器方代码。端口是80, 大家可以自己改。
include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void die(char *reason)
{
perror(reason);
exit(1);
}
int main(int argc, char *argv[])
{
int listen_sock, conn_sock;
struct sockaddr_in raddr, localaddr = {
.sin_family = PF_INET,
.sin_port = ntohs(80),
.sin_addr.s_addr = INADDR_ANY
};
int ret;
socklen_t addrlen = sizeof(raddr);
int lisnum = 10;
struct rlimit r;
int i;
int yes = 1;
listen_sock = socket(PF_INET, SOCK_STREAM, 0);
if (listen_sock < 0)
die("socket");
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
ret = bind(listen_sock, (struct sockaddr *) &localaddr, sizeof(struct
sockaddr));
if (ret < 0)
die("bind");
ret = listen(listen_sock, lisnum);
if (ret < 0)
die("listen");
for (i = 0; i < 1000000; i++) {
conn_sock = accept(listen_sock,
(struct sockaddr *)
&localaddr, &addrlen);
if (conn_sock < 0)
die("accept");
if ((i%10000) == 0 || i < 10)
printf("%dn", i);
}
return 0;
} |
S*A 发帖数: 7142 | 30 拍脑瓜的简单客户端。假设端口是 80, 启动指定服务器 IP 地址,
不用域名。当然会碰到一个 IP 地址只能发出去 65K 个连接的限制。
如何用 ip alias 使用多个 IP 地址解决这个问题留给大家自己改。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void die(char *reason)
{
perror(reason);
exit(1);
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr, localaddr;
int i,j, ret;
int total = 0;
if (argc != 2)
die("usage: a.out ");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(80);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
die("inet_pton error for arg1");
for (i=1; i < 1000000; i++) {
int so_reuseaddr = 1;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
die("socket error");
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR, &so_reuseaddr, sizeof
so_reuseaddr);
if (connect(sockfd, (struct sockaddr *) & servaddr, sizeof(
servaddr)) < 0)
die("connect error");
printf("%d\n",++total);
}
} |
|
|
b*******s 发帖数: 5216 | 31 迟一点试试看
就不用给伪币了
挺有趣的
【在 S*A 的大作中提到】 : 这个练习1 已经发现了,C10M 没有强壮的内存支持是 : 没戏的。单单是 kernel 部分就已经消耗很多内存了。 : 所以我们把目标调整一下,1M per 4G RAM。 : 这样 64G 内存就有可能实现 10M。 : 练习2 就是看看,我们如果保留 1M/4G 的空TCP : 连接,可不可以。完全不往 TCP 里面发东西。就是 : 建立连接而已。这样也不存在 epoll 问题。 : 和实验1一样,我会发些拍脑瓜想出来的简单代码。 : 你直接用这个代码冲刺 1M/4G 会碰到些实际问题。 : 有兴趣的同学跟着做一下实验,看看有没有办法解
|
d*******r 发帖数: 3299 | |
c****3 发帖数: 10787 | 33 要设SO_SNDBUF和SO_RCVBUF,否则光这两个socket buffer在Linux里的默认值,就吃掉
大量内存
【在 S*A 的大作中提到】 : 这个练习1 已经发现了,C10M 没有强壮的内存支持是 : 没戏的。单单是 kernel 部分就已经消耗很多内存了。 : 所以我们把目标调整一下,1M per 4G RAM。 : 这样 64G 内存就有可能实现 10M。 : 练习2 就是看看,我们如果保留 1M/4G 的空TCP : 连接,可不可以。完全不往 TCP 里面发东西。就是 : 建立连接而已。这样也不存在 epoll 问题。 : 和实验1一样,我会发些拍脑瓜想出来的简单代码。 : 你直接用这个代码冲刺 1M/4G 会碰到些实际问题。 : 有兴趣的同学跟着做一下实验,看看有没有办法解
|
S*A 发帖数: 7142 | 34 还没有开始发数据,好像我没有改也过了。
没准有真正数据才开始用 buffer?
你们会碰到其他险恶的问题的,哈哈哈。
【在 c****3 的大作中提到】 : 要设SO_SNDBUF和SO_RCVBUF,否则光这两个socket buffer在Linux里的默认值,就吃掉 : 大量内存
|
c****3 发帖数: 10787 | 35 不用发数据,这两个buffer是在TCP连接建立好之前设置的,建立之后就不能改了。对
应就TCP协议里的用于流控的TCP Windows size。
如果默认值是2K,发送接收4K,1M连接,光这两个buffer,就需要4G内存
【在 S*A 的大作中提到】 : 还没有开始发数据,好像我没有改也过了。 : 没准有真正数据才开始用 buffer? : 你们会碰到其他险恶的问题的,哈哈哈。
|
S*A 发帖数: 7142 | 36 我可以告诉你的是我的实验通过了,就是在4G 的笔记本上,
服务器端程序没有改。(其配置有改)。这个buffer 我的确
没有碰。你能指出 kernel allocate buffer 的代码在那里吗?
我们可以一起看看是不是空连接就已经分配 window buffer 了。
我粗略看了一下,没有在连接的时候找到。如果你很确定知道
buffer 在那里分配的,有 kernel 源程序最好。那值得研究一下
为什么我的机器没有 crash.
【在 c****3 的大作中提到】 : 不用发数据,这两个buffer是在TCP连接建立好之前设置的,建立之后就不能改了。对 : 应就TCP协议里的用于流控的TCP Windows size。 : 如果默认值是2K,发送接收4K,1M连接,光这两个buffer,就需要4G内存
|
b********e 发帖数: 595 | 37
ss -t -m试试,我印象平时是空的
另外学习别人的经验,装systemtap查。我觉得C1M问题离programming版有点远,不是
多少行代码的问题。
看链接:
http://blog.yufeng.info/archives/2511
【在 S*A 的大作中提到】 : 我可以告诉你的是我的实验通过了,就是在4G 的笔记本上, : 服务器端程序没有改。(其配置有改)。这个buffer 我的确 : 没有碰。你能指出 kernel allocate buffer 的代码在那里吗? : 我们可以一起看看是不是空连接就已经分配 window buffer 了。 : 我粗略看了一下,没有在连接的时候找到。如果你很确定知道 : buffer 在那里分配的,有 kernel 源程序最好。那值得研究一下 : 为什么我的机器没有 crash.
|
S*A 发帖数: 7142 | 38 这个问题我大概有理解了。那个tcp buffer 就是sk_buff 链。没有其它的另外buffer
,所以没有数据就是空的。
【在 b********e 的大作中提到】 : : ss -t -m试试,我印象平时是空的 : 另外学习别人的经验,装systemtap查。我觉得C1M问题离programming版有点远,不是 : 多少行代码的问题。 : 看链接: : http://blog.yufeng.info/archives/2511
|
b*******s 发帖数: 5216 | 39 昨天看了下内核的代码,新建socket就是分配了新的inode,以及你说的sk list,一个空
的双向链表,还有些structure
buffer
【在 S*A 的大作中提到】 : 这个问题我大概有理解了。那个tcp buffer 就是sk_buff 链。没有其它的另外buffer : ,所以没有数据就是空的。
|
S*A 发帖数: 7142 | 40 //hand
这个也是我的结论。那个 TCP buffer 就是在sk_buffer 链里面表示的。
【在 b*******s 的大作中提到】 : 昨天看了下内核的代码,新建socket就是分配了新的inode,以及你说的sk list,一个空 : 的双向链表,还有些structure : : buffer
|
|
|
b*******s 发帖数: 5216 | 41 http://www.linuxjournal.com/article/1312
在源代码里看到他的名字,搜了一下
【在 S*A 的大作中提到】 : //hand : 这个也是我的结论。那个 TCP buffer 就是在sk_buffer 链里面表示的。
|
b*******s 发帖数: 5216 | 42 昨天还干了件蠢事,直接给vm分了4g内存,想看看有什么区别
后来发现vm里centos是32位的
【在 S*A 的大作中提到】 : //hand : 这个也是我的结论。那个 TCP buffer 就是在sk_buffer 链里面表示的。
|
S*A 发帖数: 7142 | 43 2G/2G or 3G/1G split kernel 地址空间不够用?
【在 b*******s 的大作中提到】 : 昨天还干了件蠢事,直接给vm分了4g内存,想看看有什么区别 : 后来发现vm里centos是32位的
|
S*A 发帖数: 7142 | 44 提示一下,这个练习需要编写连接一个远程端口的时候,
使用指定的本定 IP 地址。如果让系统自动挑 IP, 系统
只会自动挑第一个满足 routing 条件的 IP,用光这个 IP
所有的端口就跑不下去了。
谁来试着改进一下程序使用指定的本地 IP? |
d*******r 发帖数: 3299 | 45 搞个 github 帐号吧,把大家的研究成果和步骤存上去 |
S*A 发帖数: 7142 | 46 我其实就是抛砖引玉而已,我大概不会把解决方案
直接贴上去,这样就没有了解决问题的乐趣。我说的
这些问题,分开拆解其实都不难对付。
github 大概会要有更加成熟的东西才会考虑贴。 |
l***e 发帖数: 450 | 47 not exactly,the so_snd and so_rcv only enforce the limit of buffer that can
be used/queued at the socket, it does not really commit any buffer space.
The buffer comes from network driver for inbound traffic, and application
for outbound traffic.
【在 c****3 的大作中提到】 : 不用发数据,这两个buffer是在TCP连接建立好之前设置的,建立之后就不能改了。对 : 应就TCP协议里的用于流控的TCP Windows size。 : 如果默认值是2K,发送接收4K,1M连接,光这两个buffer,就需要4G内存
|
c****3 发帖数: 10787 | 48 IP fragment重组是不能靠network driver的,没有buffer怎么做。
can
【在 l***e 的大作中提到】 : not exactly,the so_snd and so_rcv only enforce the limit of buffer that can : be used/queued at the socket, it does not really commit any buffer space. : The buffer comes from network driver for inbound traffic, and application : for outbound traffic.
|
S*A 发帖数: 7142 | 49 这个问题我和 brainless 在另外一个贴里面有比较深入的讨论了。
http://www.mitbbs.com/article_t1/Programming/31330685_0_7.html
这个在建立空的 TCP 连接的时候是不需要的。也就是说,现在
的 Linux 还是比较聪明的,不会在没有需要的时候把buffer 白白
预留在那里。
buffer 就是以 sk_buff 的形式存在的,是有数据进来的时候才
分配。IP fragment 就是用buffer的其中一部分,对网卡就是改
buffer地址和长度,没有什么难度。要把几个用户的send buffer
合并到一个 ip 包里面,依然可以用网卡驱动直接完成。现在网卡
有 scatter/gather list, 你可以把几个不同的buffer直接告诉网卡
用一个包发出去。只有特别老的网卡不支持 scatter/gather list.
我记得以前特别著名的 NE2000 就是那样,现在应该没有那种网卡
了。
【在 c****3 的大作中提到】 : IP fragment重组是不能靠network driver的,没有buffer怎么做。 : : can
|
b*******s 发帖数: 5216 | 50 最近我在考虑买台server做试验用,看看现在8个核,64g ram的机器也就两三千刀
和一个macbook pro开发本差不多贵
【在 S*A 的大作中提到】 : 这个问题我和 brainless 在另外一个贴里面有比较深入的讨论了。 : http://www.mitbbs.com/article_t1/Programming/31330685_0_7.html : 这个在建立空的 TCP 连接的时候是不需要的。也就是说,现在 : 的 Linux 还是比较聪明的,不会在没有需要的时候把buffer 白白 : 预留在那里。 : buffer 就是以 sk_buff 的形式存在的,是有数据进来的时候才 : 分配。IP fragment 就是用buffer的其中一部分,对网卡就是改 : buffer地址和长度,没有什么难度。要把几个用户的send buffer : 合并到一个 ip 包里面,依然可以用网卡驱动直接完成。现在网卡 : 有 scatter/gather list, 你可以把几个不同的buffer直接告诉网卡
|
|
|
S*A 发帖数: 7142 | 51 回到正题上,用 4G 内存的笔记本保持 1M 个空的 TCP 连接
我已经实验出来了。所以这一步定下的目标是可以是实现的,
大家不用过于担心 4G 不够用的问题,至少这一步不用。
还是需要在客户端改用指定的 IP 地址才能避免同一个 IP 有
65K 个端口的限制。现在我还没有看到有其他同学贴这个代码
出来。这样吧,我再放 10 个包子,给第一个贴用多个 IP 连
接的。就是简单的 socket 编程啊。
然后我再追加一个非常简单的要求,原来程序里面得到的连接
的 handle 是直接扔掉的。现在要求把得到的 handle 放到一个
大数组里面,1M TCP 就是 4M 空间,很小。然后这把柄的数
组就是下一步练习 3 epoll 要用到的。
大家加油啊。 |
j*a 发帖数: 14423 | 52 我觉得这个说得挺清楚的了:
http://stackoverflow.com/questions/1175108/
Use getifaddrs() to enumerate all the interfaces
and find the IP address for the interface you want
to bind to. Then use bind() to bind to that IP
address, before you call connect().
【在 S*A 的大作中提到】 : 回到正题上,用 4G 内存的笔记本保持 1M 个空的 TCP 连接 : 我已经实验出来了。所以这一步定下的目标是可以是实现的, : 大家不用过于担心 4G 不够用的问题,至少这一步不用。 : 还是需要在客户端改用指定的 IP 地址才能避免同一个 IP 有 : 65K 个端口的限制。现在我还没有看到有其他同学贴这个代码 : 出来。这样吧,我再放 10 个包子,给第一个贴用多个 IP 连 : 接的。就是简单的 socket 编程啊。 : 然后我再追加一个非常简单的要求,原来程序里面得到的连接 : 的 handle 是直接扔掉的。现在要求把得到的 handle 放到一个 : 大数组里面,1M TCP 就是 4M 空间,很小。然后这把柄的数
|
S*A 发帖数: 7142 | 53 代码,描述没有包子。
【在 j*a 的大作中提到】 : 我觉得这个说得挺清楚的了: : http://stackoverflow.com/questions/1175108/ : Use getifaddrs() to enumerate all the interfaces : and find the IP address for the interface you want : to bind to. Then use bind() to bind to that IP : address, before you call connect().
|
S*A 发帖数: 7142 | 54 这个说的对,我的实验也是这样干的。
只不过 interface 是我自己建立的,我不用去查看
什么 IP。查看也行,如果已经有程序建立了那 20
多个虚拟网卡。我不建议手动建立 20 个 ip alias.
等待代码。
【在 j*a 的大作中提到】 : 我觉得这个说得挺清楚的了: : http://stackoverflow.com/questions/1175108/ : Use getifaddrs() to enumerate all the interfaces : and find the IP address for the interface you want : to bind to. Then use bind() to bind to that IP : address, before you call connect().
|
S*A 发帖数: 7142 | 55 不要被我呼悠了啊,我可不保证你的 server 可以上 10M 连接啊.
如果你真的要买,搞个 Intel 的网卡,可以玩 DKDP。 看上去
DKDP 比 OpenOnLoad 可玩性高。实用不一定啊。
建议还是先用的现有的机器把实验做了,把低端机器推到极致。
确定是内存限制了你的性能,然后再上高端的机器。
【在 b*******s 的大作中提到】 : 最近我在考虑买台server做试验用,看看现在8个核,64g ram的机器也就两三千刀 : 和一个macbook pro开发本差不多贵
|
b*******s 发帖数: 5216 | 56 不光是做这个试验,反正也没几个钱,还能捣鼓点别的东西
【在 S*A 的大作中提到】 : 不要被我呼悠了啊,我可不保证你的 server 可以上 10M 连接啊. : 如果你真的要买,搞个 Intel 的网卡,可以玩 DKDP。 看上去 : DKDP 比 OpenOnLoad 可玩性高。实用不一定啊。 : 建议还是先用的现有的机器把实验做了,把低端机器推到极致。 : 确定是内存限制了你的性能,然后再上高端的机器。
|
S*A 发帖数: 7142 | 57 老实说我有点失望,没有一个同学能够贴个实现
24 楼说的用多个 IP 地址建立外部连接的C 代码。
我觉得大概也没有什么人能 follow 这个实验了。
我就直接说了后面会碰到什么问题了吧。在很多
distro 里面缺省是有 firewall 的,很容易就碰到
connection state tracking 的限制。这个解决办法
大家自己放狗吧。
在 FC 20 上,解决了这两个问题,就可以在 4G
内存的机器上保持 1M 的空 TCP 连接了。内存
更多应该连接数目更多,是线性的关系。
至于传输速率可到多少,看实验三。 |
w***g 发帖数: 5958 | 58 我一直在用一台3770K(6核)+64G内存的台式机做开发,速度比我能接触到的公司和学校
实验室的双CPU服务器都要快,也就一千来块钱。一般都是我在自己机器上调好了以后
放过去一跑咦没这么慢的呀。不知道现在有没有128G的台式机主板。
【在 b*******s 的大作中提到】 : 最近我在考虑买台server做试验用,看看现在8个核,64g ram的机器也就两三千刀 : 和一个macbook pro开发本差不多贵
|
w***g 发帖数: 5958 | 59 我印象中freebsd的TCP/IP协议栈有userspace版本的,要是能用那个做实验可能会比较
爽。刚才google了一阵没找到。可能是当时实验室那帮哥们自己port出来做benchmark
的,只在他们的benchmark中有http://parsec.cs.princeton.edu/parsec3-doc.htm#uptcpip。我印象中好像是在raw socket上面干活的。不知道配上一个kernel bypass的网卡驱动是不是就是一个完整的kernel bypass network solution。这样优化起来都会方便好多。即使暂时就用原生态的raw socket,除了速度上可能慢一星半点,用来搞C10M应该也够了。
【在 S*A 的大作中提到】 : 不要被我呼悠了啊,我可不保证你的 server 可以上 10M 连接啊. : 如果你真的要买,搞个 Intel 的网卡,可以玩 DKDP。 看上去 : DKDP 比 OpenOnLoad 可玩性高。实用不一定啊。 : 建议还是先用的现有的机器把实验做了,把低端机器推到极致。 : 确定是内存限制了你的性能,然后再上高端的机器。
|
n****1 发帖数: 1136 | 60 其实如果考虑到各种kernel space技术,c10M应该小菜一碟吧。 首先各种很多微内核
系统都能这么做,其次现在有些software fault isolation能在同一地址空间内运行多
个互不干扰的“进程”, 比如Google的nativeclient 和rackspace的zeroVM(这丫能把
zfs和应用绑在一个地址空间里,实现用户态高性能zfs)。sfi技术移植到内核空间也不
会很难
最近连linux这种单内核死忠也开始在内核空间里做jit了,目前只是用来做packet
filter,但我感觉在虚拟化的大环境下,kernel space的应用会越来越普及 |
|
|
j********x 发帖数: 2330 | 61 ip defragmentation 就是协议栈一部分吧,不给driver做谁来做?
【在 c****3 的大作中提到】 : IP fragment重组是不能靠network driver的,没有buffer怎么做。 : : can
|
h**********c 发帖数: 4120 | 62 any one who does not support this post will lose the track of his or her
career.
We program, we proud, we vely rule! |
S*A 发帖数: 7142 | 63 netmap? raw socket 不可能太快,每个 packet 至少一个系统调用,
次数太多。
benchmark
【在 w***g 的大作中提到】 : 我印象中freebsd的TCP/IP协议栈有userspace版本的,要是能用那个做实验可能会比较 : 爽。刚才google了一阵没找到。可能是当时实验室那帮哥们自己port出来做benchmark : 的,只在他们的benchmark中有http://parsec.cs.princeton.edu/parsec3-doc.htm#uptcpip。我印象中好像是在raw socket上面干活的。不知道配上一个kernel bypass的网卡驱动是不是就是一个完整的kernel bypass network solution。这样优化起来都会方便好多。即使暂时就用原生态的raw socket,除了速度上可能慢一星半点,用来搞C10M应该也够了。
|
q*c 发帖数: 9453 | 64 主要是没动力。你要哪怕悬赏 10k 刀,几天甚至几个小时代码就出来了。
否则没多少人有闲暇干这个没啥意义的事情。
【在 S*A 的大作中提到】 : 老实说我有点失望,没有一个同学能够贴个实现 : 24 楼说的用多个 IP 地址建立外部连接的C 代码。 : 我觉得大概也没有什么人能 follow 这个实验了。 : 我就直接说了后面会碰到什么问题了吧。在很多 : distro 里面缺省是有 firewall 的,很容易就碰到 : connection state tracking 的限制。这个解决办法 : 大家自己放狗吧。 : 在 FC 20 上,解决了这两个问题,就可以在 4G : 内存的机器上保持 1M 的空 TCP 连接了。内存 : 更多应该连接数目更多,是线性的关系。
|
s*****t 发帖数: 89 | 65 我以前写网卡驱动的时候是需要分配内存的,没有数据源(不管是物理设备还是虚拟设
备)什么协议栈都是空的。
可以看看这个资料
【在 c****3 的大作中提到】 : IP fragment重组是不能靠network driver的,没有buffer怎么做。 : : can
|