├── LICENSE
├── README.md
├── imgs
├── new_62_62.png
└── official_accounts.jpg
└── tests
└── network
├── index.md
├── test01
├── client.php
├── clientd.php
└── server.php
├── test02
├── c
│ ├── Makefile
│ ├── client.c
│ ├── server.c
│ └── tool.sh
├── java
│ ├── Client.java
│ ├── Makefile
│ ├── Server.java
│ └── tool.sh
└── php
│ ├── Makefile
│ ├── client.php
│ ├── server.php
│ └── tool.sh
├── test03
├── c
│ ├── Makefile
│ ├── client.c
│ ├── server.c
│ └── tool.sh
├── java
│ ├── Client.java
│ ├── Makefile
│ ├── Server.java
│ └── tool.sh
└── php
│ ├── Makefile
│ ├── client.php
│ ├── server.php
│ └── tool.sh
└── test04
└── main.c
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | **公众号: 开发内功修炼**
3 |
4 | 我们所有的开发同学每时每刻都在使用内核、都在使用硬件。所以能正确理解内核是怎么工作的、硬件的性能指标大概是多少,这些对于高阶的开发工程师来说非常重要。想成为技术大牛,扎实练习内功是必经之路!
5 |
6 | 飞哥的开发内功修炼从CPU、内存、磁盘、网络四大模块进行深度思考,总结出来,在这里分享给积极上进的你!
7 |
8 | 持续更新ing...
9 |
10 | ## 一、网络篇
11 | **1.1 内核收发包原理**
12 | - [🔥图解Linux网络包接收过程](https://mp.weixin.qq.com/s/GoYDsfy9m0wRoXi_NCfCmg)
13 | - [🔥25 张图,一万字,拆解 Linux 网络包发送过程](https://mp.weixin.qq.com/s/wThfD9th9e_-YGHJJ3HXNQ)
14 | - [🔥127.0.0.1 之本机网络通信过程知多少 ?!](https://mp.weixin.qq.com/s/6_OfoeD3ZpyQisY2F-4_bw)
15 | - [Linux网络包接收过程的监控与调优](https://mp.weixin.qq.com/s/6iQ-OhEbQJbEcgi9kakSjg)
16 |
17 | **1.2 内核如何与用户进程协作**
18 | - [图解 | 深入理解高性能网络开发路上的绊脚石 - 同步阻塞网络 IO](https://mp.weixin.qq.com/s/cIcw0S-Q8pBl1-WYN0UwnA)
19 | - [🔥图解 | 深入揭秘 epoll 是如何实现 IO 多路复用的!](https://mp.weixin.qq.com/s/OmRdUgO1guMX76EdZn11UQ)
20 | - [漫画 | 看进程小 P 讲述它的网络性能故事!](https://mp.weixin.qq.com/s/r7EDYsvVhWA2fv52mwM_zg)
21 |
22 | **1.3 TCP之三次握手**
23 | - [为什么服务端程序都需要先 listen 一下?](https://mp.weixin.qq.com/s/hv2tmtVpxhVxr6X-RNWBsQ) (:cn:新)
24 | - [TCP连接中客户端的端口号是如何确定的?](https://mp.weixin.qq.com/s/C-Eeoeh9GHxugF4J30fz1A) (:cn:新)
25 | - [能将三次握手理解到这个深度,面试官拍案叫绝!](https://mp.weixin.qq.com/s/vlrzGc5bFrPIr9a7HIr2eA) (:cn:新)
26 | - [深入解析常见三次握手异常](https://mp.weixin.qq.com/s/7Cum6Y28H_gXLyrRFrthNw) (:cn:新)
27 | - [如何正确查看线上半/全连接队列溢出情况?](https://mp.weixin.qq.com/s/f-TFX2t8CWRCGoyCByGkOw) (:cn:新)
28 |
29 | **1.4 TCP连接时间开销、内存开销**
30 | - [聊聊TCP连接耗时的那些事儿](https://mp.weixin.qq.com/s/wXyerOFoibRsaBmbl224gw)
31 | - [刨根问底儿,看我如何处理 Too many open files 错误!](https://mp.weixin.qq.com/s/GBn94vdL4xUL80WYrGdUWQ)、
32 | - [漫画 | 花了七天时间测试,我彻底搞明白了 TCP 的这些内存开销!](https://mp.weixin.qq.com/s/BwddYkVLSYlkKFNeA-NUVg)
33 |
34 | **1.5 单机百万并发系列**
35 | - [🔥漫画 | 一台Linux服务器最多能支撑多少个TCP连接](https://mp.weixin.qq.com/s/Lkyj42NtvqEj63DoCY5btQ)
36 | - [🔥漫画 | 理解了TCP连接的实现以后,客户端的并发也爆发了!](https://mp.weixin.qq.com/s/ta6upubg0o1w03YGUo8Trg)
37 | - [百看不如一练,动手测试单机百万连接的保姆级教程!](https://mp.weixin.qq.com/s/f_CMt2ni0vegB3-pf2BTTg)
38 |
39 | **1.6 网络工具**
40 | - [用户态 tcpdump 如何实现抓到内核网络包的?](https://mp.weixin.qq.com/s/ZX8Jluh-RgJXcVh3OvycRQ) (:cn:新)
41 |
42 | **1.7 电子书**
43 | - [🔥开发内功修炼网络篇电子书出炉!!!](https://mp.weixin.qq.com/s/kE8y9em9a0Xv80YaQqPbRg)
44 |
45 | ## 二、硬盘篇
46 | **2.1 硬件工作原理**
47 | - [磁盘开篇:扒开机械硬盘坚硬的外衣!](https://mp.weixin.qq.com/s/OqhwSI4WsEyZlBhkFGPUlg)
48 | - [磁盘分区也是隐含了技术技巧的](https://mp.weixin.qq.com/s/4HwUxy-4FClgIIei6JAzqw)
49 | - [我们怎么解决机械硬盘既慢又容易坏的问题?](https://mp.weixin.qq.com/s/n9Hf3Utm4NFp3jNRTgZNwg)
50 | - [拆解固态硬盘结构](https://mp.weixin.qq.com/s/6aPHMmz1kmiaBABhy8pF1Q)
51 |
52 | **2.2 文件系统浅析**
53 | - [新建一个空文件占用多少磁盘空间?](https://mp.weixin.qq.com/s/9YeUEnRnegplftpKlW4ZCA)
54 | - [只有1个字节的文件实际占用多少磁盘空间](https://mp.weixin.qq.com/s/WE6BodR_q0GSKks_TgYL1w)
55 | - [文件过多时ls命令为什么会卡住?](https://mp.weixin.qq.com/s/g-fFoYsBJkonV3ezdGDJKA)
56 | - [理解格式化原理](https://mp.weixin.qq.com/s/DobymgQ-TRXrO32wjf2fWQ)
57 |
58 | **2.3 文件读写性能**
59 | - [read文件一个字节实际会发生多大的磁盘IO?](https://mp.weixin.qq.com/s/vekemOfUHBjZSy3uXb49Rw) (:cn:新)
60 | - [write文件一个字节后何时发起写磁盘IO?](https://zhuanlan.zhihu.com/p/142441899)
61 | - [机械硬盘随机IO慢的超乎你的想象](https://mp.weixin.qq.com/s/qz57uPtFaoQ_5z59NSBEUQ)
62 | - [搭载固态硬盘的服务器究竟比搭机械硬盘快多少?](https://mp.weixin.qq.com/s/4CKPLpEDDbIyqJGxYDAUeA)
63 |
64 |
65 | ## 三、内存篇
66 | **3.1 硬件工作原理**
67 | - [带你深入理解内存对齐最底层原理](https://mp.weixin.qq.com/s/F0NTfz-3x3UxQeF-GSavRg)
68 | - [内存随机也比顺序访问慢,带你深入理解内存IO过程](https://mp.weixin.qq.com/s/ps8VfGpbL4-xKggM2ywjHw)
69 | - [从DDR到DDR4,内存核心频率其实基本上就没太大的进步](https://mp.weixin.qq.com/s/LRxhKrUOgyCexYN1lOwTyA)
70 |
71 | **3.2 内核内存管理**
72 | - [说出来你可能不信,内核这家伙在内存的使用上给自己开了个小灶!](https://mp.weixin.qq.com/s/OR2XB4J76haGc1THeq7WQg) (:cn:新)
73 |
74 | **3.3 内存性能测试**
75 | - [实际测试内存在顺序IO和随机IO时的访问延时差异](https://mp.weixin.qq.com/s/_-Ar944KlztzmFYdA3JXnQ)
76 | - [揭穿内存厂家“谎言”,实测内存带宽真实表现](https://mp.weixin.qq.com/s/AJjBHCNPWN8YW8v0iXjjig)
77 | - [NUMA架构下的内存访问延迟区别!](https://mp.weixin.qq.com/s/xUZl5wGRVvJI_Hfivg0hVQ)
78 | - [挑战Redis单实例内存最大极限,“遭遇”NUMA陷阱!](https://mp.weixin.qq.com/s/dag1Zp1h4lQfqeUUGz4Ogw)
79 |
80 | **3.4 内存性能优化实例**
81 | - [一次内存性能提升的项目实践](https://mp.weixin.qq.com/s/foJJ2E7_jVgnOeJ9Du6qJg)
82 | - [PHP7内存性能优化的思想精髓](https://mp.weixin.qq.com/s/3DrDb0CY8dUmFUKtuWzhqA)
83 |
84 |
85 | ## 四、CPU篇
86 | **4.1 了解CPU硬件**
87 | - [你以为你的多核CPU都是真核吗?多核“假象”](https://mp.weixin.qq.com/s/XX1yh8BTgT256pAnfosQkw)
88 | - [听说你只知内存,而不知缓存?CPU表示很伤心!](https://mp.weixin.qq.com/s/PQTuFZO51an6OAe3WX4BVw)
89 | - [TLB缓存是个神马鬼,如何查看TLB miss?](https://mp.weixin.qq.com/s/mssTS3NN7-w2df1vhYSuYw)
90 |
91 | **4.2 内核CPU开销浅析**
92 | - [进程/线程切换究竟需要多少开销?](https://mp.weixin.qq.com/s/uq5s5vwk5vtPOZ30sfNsOg)
93 | - [软中断会吃掉你多少CPU?](https://mp.weixin.qq.com/s/mlenlX3-6H0shfOIvi8E8g)
94 | - [一次系统调用开销到底有多大?](https://mp.weixin.qq.com/s/2nIDLeMR984_Sdgh01BHIQ)
95 | - [一次简单的php请求redis会有哪些开销?](https://mp.weixin.qq.com/s/yl5EuQ1wEXDuIg4E98QfZA)
96 |
97 | **4.3 用户态CPU开销分析**
98 | - [协程究竟比线程牛在什么地方?](https://mp.weixin.qq.com/s/N4W0-0cP1wlxtLILx3oXpg)
99 | - [函数调用太多了会有性能问题吗?](https://mp.weixin.qq.com/s/G30VtOIYjx2Wa54xlO7udw)
100 |
101 | ## 五、应用篇
102 | - [峰值 QPS 50 万 +,性能优异的网络框架开源力作 Sogou Workflow!](https://mp.weixin.qq.com/s/clILKrOO7_XJs6uHp5hoUw) (:cn:新)
103 |
104 | ## 六、公众号二维码
105 | **微信扫一扫关注!**
106 | 
107 |
--------------------------------------------------------------------------------
/imgs/new_62_62.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/coder-kung-fu/b3a5c5750330d673ed2570a48e9674c98f630b48/imgs/new_62_62.png
--------------------------------------------------------------------------------
/imgs/official_accounts.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/coder-kung-fu/b3a5c5750330d673ed2570a48e9674c98f630b48/imgs/official_accounts.jpg
--------------------------------------------------------------------------------
/tests/network/index.md:
--------------------------------------------------------------------------------
1 |
2 | - [通过多 IP 达成单机百万连接](tests/network/test02)
3 | - [通过端口重用达成单机百万连接](tests/network/test03)
4 | - [一个模拟 tcpdump 的简单抓包程序](tests/network/test04)
--------------------------------------------------------------------------------
/tests/network/test01/client.php:
--------------------------------------------------------------------------------
1 | $ip){
47 | echo $ip.":".pingAddress($ip)."\n";
48 | }
49 | break;
50 |
51 | case "ifup":
52 | foreach($ips as $k=>$ip){
53 | shell_exec("ifconfig eth0:$k $ip netmask ".$netmask." up");
54 | }
55 | break;
56 |
57 | case "ifdown":
58 | foreach($ips as $k=>$ip){
59 | shell_exec("ifconfig eth0:$k down");
60 | }
61 | break;
62 |
63 | case "start":
64 | $cmd = "ps -ef | grep client.php | awk '{print $2}' | xargs kill -9";
65 | shell_exec($cmd);
66 | shell_exec("echo '' > clientd.log");
67 |
68 | foreach($ips as $ip){
69 | $cmd = "php client.php $ip $serverIp $serverPort >> clientd.log &";
70 | echo $cmd."\n";
71 | shell_exec($cmd);
72 | }
73 | break;
74 |
75 | case "stop":
76 | $cmd = "ps -ef | grep client.php | awk '{print $2}' | xargs kill -9";
77 | shell_exec($cmd);
78 | break;
79 |
80 | default:
81 | break;
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/tests/network/test01/server.php:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define MAX_CONNECTION_NUM 50000
9 |
10 | int buildConnect(const char *lIp, const char *sIp, int sPort)
11 | {
12 | int skFd;
13 | if((skFd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
14 | {
15 | printf("\n Error : Could not create socket\n");
16 | return 0;
17 | }
18 |
19 | struct sockaddr_in cliAddr;
20 | cliAddr.sin_family = AF_INET;
21 | cliAddr.sin_addr.s_addr = inet_addr(lIp);
22 | cliAddr.sin_port = 0;
23 | if(bind(skFd, (struct sockaddr *)&cliAddr, sizeof(cliAddr)) < 0)
24 | {
25 | printf("\n Error : Bind Failed \n");
26 | }
27 |
28 | struct sockaddr_in srvAddr;
29 | srvAddr.sin_family = AF_INET;
30 | srvAddr.sin_addr.s_addr = inet_addr(sIp);
31 | srvAddr.sin_port = htons(sPort);
32 | if(connect(skFd, (struct sockaddr *)&srvAddr, sizeof(srvAddr)) < 0)
33 | {
34 | printf("\n Error : Connect Failed \n");
35 | return 0;
36 | }
37 |
38 | return skFd;
39 | }
40 |
41 | int main(int argc, char *argv[])
42 | {
43 | int i = 0, sPort, fd;
44 | char lIp[16], sIp[16];
45 |
46 | if(argc != 4)
47 | {
48 | printf("\n Usage: %s \n", argv[0]);
49 | return 1;
50 | }
51 |
52 | //1. 从命令行获取并解析local ip、server ip以及端口
53 | strcpy(lIp, argv[1]);
54 | strcpy(sIp, argv[2]);
55 | sPort = atoi(argv[3]);
56 |
57 | //2. 开始建立连接
58 | int *sockets = (int *)malloc(sizeof(int) * MAX_CONNECTION_NUM);
59 | for(i = 1; i <= MAX_CONNECTION_NUM; i++)
60 | {
61 | if(0 == i % 1000)
62 | {//稍稍停顿一下,避免把服务端的握手队列打满
63 | printf("%s 连接 %s:%d成功了 %d 条!\n", lIp, sIp, sPort, i);
64 | sleep(1);
65 | }
66 |
67 | fd = buildConnect(lIp, sIp, sPort);
68 | if(fd > 0)
69 | {
70 | sockets[i-1] = fd;
71 | }else{
72 | return 1;
73 | }
74 | }
75 | sleep(300);
76 |
77 | //3. 释放所有的连接
78 | printf("关闭所有的连接...\n");
79 | for(i = 0; i < MAX_CONNECTION_NUM; i++)
80 | {
81 | close(sockets[i]);
82 | }
83 |
84 | return 0;
85 | }
86 |
--------------------------------------------------------------------------------
/tests/network/test02/c/server.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #define MAX_CONNECTION_NUM 1100000
7 |
8 | int main(int argc, char *argv[])
9 | {
10 | char ip[16];
11 | int lisFd, conFd, port;
12 | struct sockaddr_in servAddr;
13 |
14 | if(argc != 3)
15 | {
16 | printf("\n Usage: %s \n", argv[0]);
17 | return 1;
18 | }
19 |
20 | //1. 从命令行获取并解析server ip以及端口
21 | strcpy(ip, argv[1]);
22 | port = atoi(argv[2]);
23 |
24 | //2. 创建server
25 | if((lisFd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
26 | {
27 | printf("\n Error : Could not create socket\n");
28 | return 0;
29 | }
30 |
31 | servAddr.sin_family = AF_INET;
32 | servAddr.sin_addr.s_addr = inet_addr(ip);
33 | servAddr.sin_port = htons(port);
34 | if(bind(lisFd, (struct sockaddr*)&servAddr, sizeof(servAddr)) < 0)
35 | {
36 | printf("\n Error : Bind Failed \n");
37 | }
38 | if((listen(lisFd, 1024)) < 0)
39 | {
40 | printf("\n Error : Listen Failed \n");
41 | }
42 |
43 | //3. 接收连接
44 | int i = 0;
45 | int *sockets = (int *)malloc(sizeof(int) * MAX_CONNECTION_NUM);
46 | while(1)
47 | {
48 | conFd = accept(lisFd, (struct sockaddr*)NULL, NULL);
49 | if(conFd > 0)
50 | {
51 | sockets[i++] = conFd;
52 | printf("%s %d accept success:%d\n", ip, port, i);
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/tests/network/test02/c/tool.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #--------------------------- begin -------------------------
4 | #注意:这一部分的内容需要根据你自己的实验环境来设置
5 |
6 | #1.客户端 IP 列表:选择20个,且不能在局域网中存在
7 | # 示例
8 | # IPS=(
9 | # "192.168.1.200"
10 | # "192.168.1.201"
11 | # )
12 |
13 | IPS=(
14 | "192.168.1.200"
15 | "192.168.1.201"
16 | )
17 |
18 | #2.客户端 IP 对应的子网掩码
19 | #示例:
20 | #NETMASK="255.255.248.0"
21 | NETMASK="255.255.248.0"
22 |
23 | #3.服务端的 IP 和 端口
24 | #示例
25 | #SERVERIP="192.168.1.100"
26 | #SERVERPORT="8090"
27 | SERVERIP="192.168.1.100"
28 | SERVERPORT="8090"
29 | #--------------------------- end -------------------------
30 |
31 | TYPE=$1
32 |
33 | exec_ping(){
34 | for i in "${!IPS[@]}"; do
35 | ping -c 1 -W 1 ${IPS[$i]} > /dev/null
36 | if [[ $? != 0 ]];then
37 | echo ${IPS[$i]}" false"
38 | else
39 | echo ${IPS[$i]}" true"
40 | fi
41 | done
42 | }
43 |
44 | exec_ifup(){
45 | for i in "${!IPS[@]}"; do
46 | echo ifconfig eth0:$i ${IPS[$i]} netmask $NETMASK up
47 | ifconfig eth0:$i ${IPS[$i]} netmask $NETMASK up
48 | done
49 | }
50 |
51 | exec_ifdown(){
52 | for i in "${!IPS[@]}"; do
53 | echo ifconfig eth0:$i down
54 | ifconfig eth0:$i down
55 | done
56 | }
57 |
58 | exec_runcli(){
59 | for i in "${!IPS[@]}"; do
60 | echo $CLIENT ${IPS[$i]} $SERVERIP $SERVERPORT
61 | $CLIENT ${IPS[$i]} $SERVERIP $SERVERPORT &
62 | done
63 | }
64 |
65 | exec_stopcli(){
66 | ps -ef | grep $CLIENT | awk '{print $2}' | xargs kill -9 > /dev/null
67 | }
68 |
69 | exec_runsrv(){
70 | echo $SERVER 0.0.0.0 $SERVERPORT
71 | $SERVER 0.0.0.0 $SERVERPORT
72 | }
73 |
74 | case $TYPE in
75 | "ping") exec_ping;;
76 | "ifup") exec_ifup;;
77 | "ifdown") exec_ifdown;;
78 | "runcli") CLIENT=$2; exec_runcli;;
79 | "stopcli") CLIENT=$2; exec_stopcli;;
80 | "runsrv") SERVER=$2; exec_runsrv;;
81 | *) echo "get unkown type $TYPE"; exit ;;
82 | esac
83 |
84 |
--------------------------------------------------------------------------------
/tests/network/test02/java/Client.java:
--------------------------------------------------------------------------------
1 | import java.net.Socket;
2 | import java.net.InetSocketAddress;
3 |
4 | public class Client {
5 |
6 | public static final int MAX_CONNECTION_NUM = 50000;
7 |
8 | public static void main(String[] args) throws Exception {
9 | if(3 != args.length){
10 | System.out.println("Usage: java Client \n");
11 | return;
12 | }
13 |
14 | //1. 从命令行获取并解析local ip、server ip以及端口
15 | String lIp = args[0];
16 | String sIp = args[1];
17 | int sPort = Integer.parseInt(args[2]);
18 |
19 | //2. 开始建立连接
20 | //用数组将 socket 保存起来,防止连接被过早释放
21 | Socket[] sockets = new Socket[MAX_CONNECTION_NUM];
22 | for(int i = 1; i <= MAX_CONNECTION_NUM; i++){
23 | try {
24 | Socket s = new Socket();
25 | s.bind(new InetSocketAddress(lIp, 0));
26 | s.connect(new InetSocketAddress(sIp, sPort));
27 |
28 | if(false == s.isConnected()){
29 | System.out.println(lIp + " 连接 "+sIp+":"+sPort+" 失败! ");
30 | return;
31 | }
32 | sockets[i-1] = s;
33 |
34 | } catch (Exception e) {
35 | //连接失败则小憩一会儿接着连
36 | Thread.sleep(500);
37 | e.printStackTrace();
38 | }
39 |
40 | //稍稍停顿一下,避免把服务端的握手队列打满
41 | if(0 == i % 500){
42 | Thread.sleep(500);
43 | System.out.println(lIp + " 连接 "+sIp+":"+sPort+" 成功了 "+i+" 条");
44 | }
45 | }
46 |
47 | //把所有连接都 hold 一会儿,方便观察
48 | Thread.sleep(300 * 1000);
49 |
50 | //3. 释放所有的连接
51 | System.out.println("关闭所有的连接...\n");
52 | for(int i = 0; i < MAX_CONNECTION_NUM; i++){
53 | sockets[i].close();
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/tests/network/test02/java/Makefile:
--------------------------------------------------------------------------------
1 | CLIENT_BINARY_NAME := "java Client"
2 | SERVER_BINARY_NAME := "java Server"
3 |
4 | .PHONY: ping
5 | ping:
6 | sh tool.sh ping
7 |
8 | .PHONY: ifup
9 | ifup:
10 | sh tool.sh ifup
11 |
12 | .PHONY: ifdown
13 | ifdown:
14 | sh tool.sh ifdown
15 |
16 | .PHONY: build-cli
17 | build-cli:
18 | javac Client.java
19 |
20 | .PHONY: run-cli
21 | run-cli: build-cli
22 | sh tool.sh runcli $(CLIENT_BINARY_NAME)
23 |
24 | .PHONY: stop-cli
25 | stop-cli:
26 | sh tool.sh stopcli
27 |
28 | .PHONY: build-srv
29 | build-srv:
30 | javac Server.java
31 |
32 | .PHONY: run-srv
33 | run-srv: build-srv
34 | sh tool.sh runsrv $(SERVER_BINARY_NAME)
35 |
36 | .PHONY: clean
37 | clean:
38 | rm -f *.class
39 |
--------------------------------------------------------------------------------
/tests/network/test02/java/Server.java:
--------------------------------------------------------------------------------
1 | import java.io.IOException;
2 | import java.net.ServerSocket;
3 | import java.net.Socket;
4 | import java.net.InetSocketAddress;
5 |
6 | public class Server {
7 | public static final int MAX_CONNECTION_NUM = 1100000;
8 |
9 | public static void main(String[] args) {
10 | if(2 != args.length){
11 | System.out.println("Usage: java Server \n");
12 | return;
13 | }
14 |
15 | String sIp = args[0];
16 | int sPort = Integer.parseInt(args[1]);
17 |
18 | //用数组将 socket 保存起来,防止连接被过早回收
19 | Socket[] sockets = new Socket[MAX_CONNECTION_NUM];
20 |
21 | try {
22 | ServerSocket ss = new ServerSocket();
23 | ss.bind(new InetSocketAddress(sIp, sPort), 1024);
24 | System.out.println("启动Server " + sIp + ":" + sPort + "...");
25 |
26 | int i = 0;
27 | while(true){
28 | try{
29 | Socket s = ss.accept();
30 | sockets[i] = s;
31 | i++;
32 | System.out.println("Server " + sIp + ":" + sPort + " 接收到第 " + i +" 条连接!");
33 | } catch (IOException e) {
34 | e.printStackTrace();
35 | }
36 | }
37 | } catch (IOException e) {
38 | e.printStackTrace();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/tests/network/test02/java/tool.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #--------------------------- begin -------------------------
4 | #注意:这一部分的内容需要根据你自己的实验环境来设置
5 |
6 | #1.客户端 IP 列表:选择20个,且不能在局域网中存在
7 | # 示例
8 | # IPS=(
9 | # "192.168.1.200"
10 | # "192.168.1.201"
11 | # )
12 |
13 | IPS=(
14 | "192.168.1.200"
15 | "192.168.1.201"
16 | )
17 |
18 | #2.客户端 IP 对应的子网掩码
19 | #示例:
20 | #NETMASK="255.255.248.0"
21 | NETMASK="255.255.248.0"
22 |
23 | #3.服务端的 IP 和 端口
24 | #示例
25 | #SERVERIP="192.168.1.100"
26 | #SERVERPORT="8090"
27 | SERVERIP="192.168.1.100"
28 | SERVERPORT="8090"
29 | #--------------------------- end -------------------------
30 |
31 | TYPE=$1
32 |
33 | exec_ping(){
34 | for i in "${!IPS[@]}"; do
35 | ping -c 1 -W 1 ${IPS[$i]} > /dev/null
36 | if [[ $? != 0 ]];then
37 | echo ${IPS[$i]}" false"
38 | else
39 | echo ${IPS[$i]}" true"
40 | fi
41 | done
42 | }
43 |
44 | exec_ifup(){
45 | for i in "${!IPS[@]}"; do
46 | echo ifconfig eth0:$i ${IPS[$i]} netmask $NETMASK up
47 | ifconfig eth0:$i ${IPS[$i]} netmask $NETMASK up
48 | done
49 | }
50 |
51 | exec_ifdown(){
52 | for i in "${!IPS[@]}"; do
53 | echo ifconfig eth0:$i down
54 | ifconfig eth0:$i down
55 | done
56 | }
57 |
58 | exec_runcli(){
59 | for i in "${!IPS[@]}"; do
60 | echo $CLIENT ${IPS[$i]} $SERVERIP $SERVERPORT
61 | $CLIENT ${IPS[$i]} $SERVERIP $SERVERPORT &
62 | done
63 | }
64 |
65 | exec_stopcli(){
66 | ps -ef | grep java | grep Client | awk '{print $2}' | xargs kill -9
67 | }
68 |
69 | exec_runsrv(){
70 | echo $SERVER 0.0.0.0 $SERVERPORT
71 | $SERVER 0.0.0.0 $SERVERPORT
72 | }
73 |
74 | case $TYPE in
75 | "ping") exec_ping;;
76 | "ifup") exec_ifup;;
77 | "ifdown") exec_ifdown;;
78 | "runcli") CLIENT=$2; exec_runcli;;
79 | "stopcli") CLIENT=$2; exec_stopcli;;
80 | "runsrv") SERVER=$2; exec_runsrv;;
81 | *) echo "get unkown type $TYPE"; exit ;;
82 | esac
83 |
84 |
--------------------------------------------------------------------------------
/tests/network/test02/php/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: ping
2 | ping:
3 | sh tool.sh ping
4 |
5 | .PHONY: ifup
6 | ifup:
7 | sh tool.sh ifup
8 |
9 | .PHONY: ifdown
10 | ifdown:
11 | sh tool.sh ifdown
12 |
13 | .PHONY: run-cli
14 | run-cli:
15 | sh tool.sh runcli
16 |
17 | .PHONY: stop-cli
18 | stop-cli:
19 | sh tool.sh stopcli
20 |
21 | .PHONY: run-srv
22 | run-srv:
23 | sh tool.sh runsrv
24 |
--------------------------------------------------------------------------------
/tests/network/test02/php/client.php:
--------------------------------------------------------------------------------
1 | /dev/null
36 | if [[ $? != 0 ]];then
37 | echo ${IPS[$i]}" false"
38 | else
39 | echo ${IPS[$i]}" true"
40 | fi
41 | done
42 | }
43 |
44 | exec_ifup(){
45 | for i in "${!IPS[@]}"; do
46 | echo ifconfig eth0:$i ${IPS[$i]} netmask $NETMASK up
47 | ifconfig eth0:$i ${IPS[$i]} netmask $NETMASK up
48 | done
49 | }
50 |
51 | exec_ifdown(){
52 | for i in "${!IPS[@]}"; do
53 | echo ifconfig eth0:$i down
54 | ifconfig eth0:$i down
55 | done
56 | }
57 |
58 | exec_runcli(){
59 | for i in "${!IPS[@]}"; do
60 | echo php client.php ${IPS[$i]} $SERVERIP $SERVERPORT &
61 | php client.php ${IPS[$i]} $SERVERIP $SERVERPORT &
62 | done
63 | }
64 |
65 | exec_stopcli(){
66 | ps -ef | grep client.php | awk '{print $2}' | xargs kill -9
67 | }
68 |
69 | exec_runsrv(){
70 | echo php server.php 0.0.0.0 $SERVERPORT
71 | php server.php 0.0.0.0 $SERVERPORT
72 | }
73 |
74 | case $TYPE in
75 | "ping") exec_ping;;
76 | "ifup") exec_ifup;;
77 | "ifdown") exec_ifdown;;
78 | "runcli") exec_runcli;;
79 | "stopcli") exec_stopcli;;
80 | "runsrv") exec_runsrv;;
81 | *) echo "get unkown type $TYPE"; exit ;;
82 | esac
83 |
84 |
--------------------------------------------------------------------------------
/tests/network/test03/c/Makefile:
--------------------------------------------------------------------------------
1 | CLIENT_BINARY_NAME := "test-client"
2 | SERVER_BINARY_NAME := "test-server"
3 |
4 | .PHONY: build-cli
5 | build-cli:
6 | gcc client.c -o $(CLIENT_BINARY_NAME)
7 |
8 | .PHONY: run-cli
9 | run-cli: build-cli
10 | sh tool.sh runcli ./$(CLIENT_BINARY_NAME)
11 |
12 | .PHONY: stop-cli
13 | stop-cli:
14 | sh tool.sh stopcli ./$(CLIENT_BINARY_NAME)
15 |
16 | .PHONY: build-srv
17 | build-srv:
18 | gcc server.c -o $(SERVER_BINARY_NAME)
19 |
20 | .PHONY: run-srv
21 | run-srv: build-srv
22 | sh tool.sh runsrv ./$(SERVER_BINARY_NAME)
23 |
24 | .PHONY: stop-srv
25 | stop-srv:
26 | sh tool.sh stopsrv ./$(SERVER_BINARY_NAME)
27 |
28 | .PHONY: clean
29 | clean:
30 | rm -f ${CLIENT_BINARY_NAME}
31 | rm -f $(SERVER_BINARY_NAME)
32 |
--------------------------------------------------------------------------------
/tests/network/test03/c/client.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 |
9 | #define MAX_CONNECTION_NUM 50000
10 |
11 | int buildConnect(const char *sIp, int sPort)
12 | {
13 | int skFd;
14 | if((skFd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
15 | {
16 | printf("\n Error : Could not create socket\n");
17 | return 0;
18 | }
19 |
20 | struct sockaddr_in srvAddr;
21 | srvAddr.sin_family = AF_INET;
22 | srvAddr.sin_addr.s_addr = inet_addr(sIp);
23 | srvAddr.sin_port = htons(sPort);
24 | if(connect(skFd, (struct sockaddr *)&srvAddr, sizeof(srvAddr)) < 0)
25 | {
26 | printf("\n Error : Connect Failed \n");
27 | return 0;
28 | }
29 |
30 | return skFd;
31 | }
32 |
33 | int main(int argc, char *argv[])
34 | {
35 | int i = 0, sPort, fd;
36 | char sIp[16];
37 |
38 | if(argc != 3)
39 | {
40 | printf("\n Usage: %s \n", argv[0]);
41 | return 1;
42 | }
43 |
44 | //1. 从命令行获取并解析server ip以及端口
45 | strcpy(sIp, argv[1]);
46 | sPort = atoi(argv[2]);
47 |
48 | //2. 开始建立连接
49 | int *sockets = (int *)malloc(sizeof(int) * MAX_CONNECTION_NUM);
50 | for(i = 1; i <= MAX_CONNECTION_NUM; i++)
51 | {
52 | if(0 == i % 1000)
53 | {//稍稍停顿一下,避免把服务端的握手队列打满
54 | printf("连接 %s:%d成功了 %d 条!\n", sIp, sPort, i);
55 | sleep(1);
56 | }
57 |
58 | fd = buildConnect(sIp, sPort);
59 | if(fd > 0)
60 | {
61 | sockets[i-1] = fd;
62 | }else{
63 | return 1;
64 | }
65 | }
66 | sleep(300);
67 |
68 | //3. 释放所有的连接
69 | printf("关闭所有的连接...\n");
70 | for(i = 0; i < MAX_CONNECTION_NUM; i++)
71 | {
72 | close(sockets[i]);
73 | }
74 |
75 | return 0;
76 | }
77 |
--------------------------------------------------------------------------------
/tests/network/test03/c/server.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #define MAX_CONNECTION_NUM 1100000
7 |
8 | int main(int argc, char *argv[])
9 | {
10 | char ip[16];
11 | int lisFd, conFd, port;
12 | struct sockaddr_in servAddr;
13 |
14 | if(argc != 3)
15 | {
16 | printf("\n Usage: %s \n", argv[0]);
17 | return 1;
18 | }
19 |
20 | //1. 从命令行获取并解析server ip以及端口
21 | strcpy(ip, argv[1]);
22 | port = atoi(argv[2]);
23 |
24 | //2. 创建server
25 | if((lisFd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
26 | {
27 | printf("\n Error : Could not create socket\n");
28 | return 0;
29 | }
30 |
31 | servAddr.sin_family = AF_INET;
32 | servAddr.sin_addr.s_addr = inet_addr(ip);
33 | servAddr.sin_port = htons(port);
34 | if(bind(lisFd, (struct sockaddr*)&servAddr, sizeof(servAddr)) < 0)
35 | {
36 | printf("\n Error : Bind Failed \n");
37 | }
38 | if((listen(lisFd, 1024)) < 0)
39 | {
40 | printf("\n Error : Listen Failed \n");
41 | }
42 |
43 | //3. 接收连接
44 | int i = 0;
45 | int *sockets = (int*)malloc(sizeof(int) * MAX_CONNECTION_NUM);
46 | while(1)
47 | {
48 | conFd = accept(lisFd, (struct sockaddr*)NULL, NULL);
49 | if(conFd > 0)
50 | {
51 | sockets[i++] = conFd;
52 | printf("%s %d accept success:%d\n", ip, port, i);
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/tests/network/test03/c/tool.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #--------------------------- begin -------------------------
4 | #注意:这一部分的内容需要根据你自己的实验环境来设置
5 |
6 | #1.服务端的 IP
7 | #示例
8 | #SERVERIP="192.168.1.100"
9 | SERVERIP="192.168.1.100"
10 |
11 | #2.服务端的端口
12 | SERVERPORTS=(
13 | "8100"
14 | "8101"
15 | "8102"
16 | "8103"
17 | "8104"
18 | "8105"
19 | "8106"
20 | "8107"
21 | "8108"
22 | "8109"
23 | "8110"
24 | "8111"
25 | "8112"
26 | "8113"
27 | "8114"
28 | "8115"
29 | "8116"
30 | "8117"
31 | "8118"
32 | "8119"
33 | )
34 | #--------------------------- end -------------------------
35 |
36 | TYPE=$1
37 |
38 | exec_runcli(){
39 | for i in "${!SERVERPORTS[@]}"; do
40 | echo $CLIENT $SERVERIP ${SERVERPORTS[$i]} &
41 | $CLIENT $SERVERIP ${SERVERPORTS[$i]} &
42 | done
43 | }
44 |
45 | exec_stopcli(){
46 | ps -ef | grep $CLIENT | awk '{print $2}' | xargs kill -9
47 | }
48 |
49 | exec_runsrv(){
50 | for i in "${!SERVERPORTS[@]}"; do
51 | echo $SERVER 0.0.0.0 ${SERVERPORTS[$i]} &
52 | $SERVER 0.0.0.0 ${SERVERPORTS[$i]} &
53 | done
54 | }
55 |
56 | exec_stopsrv(){
57 | ps -ef | grep $SERVER | awk '{print $2}' | xargs kill -9
58 | }
59 |
60 | case $TYPE in
61 | "runcli") CLIENT=$2; exec_runcli;;
62 | "stopcli") CLIENT=$2; exec_stopcli;;
63 | "runsrv") SERVER=$2; exec_runsrv;;
64 | "stopsrv") SERVER=$2; exec_stopsrv;;
65 | *) echo "get unkown type $TYPE"; exit ;;
66 | esac
67 |
68 |
--------------------------------------------------------------------------------
/tests/network/test03/java/Client.java:
--------------------------------------------------------------------------------
1 | import java.net.Socket;
2 | import java.net.InetSocketAddress;
3 |
4 | public class Client {
5 | public static final int MAX_CONNECTION_NUM = 50000;
6 |
7 | public static void main(String[] args) throws Exception {
8 | if(2 != args.length){
9 | System.out.println("Usage: java Client \n");
10 | return;
11 | }
12 |
13 | //1. 从命令行获取并解析local ip、server ip以及端口
14 | String sIp = args[0];
15 | int sPort = Integer.parseInt(args[1]);
16 |
17 | //2. 开始建立连接
18 | //用数组将 socket 保存起来,防止连接被过早释放
19 | Socket[] sockets = new Socket[MAX_CONNECTION_NUM];
20 | for(int i = 1; i <= MAX_CONNECTION_NUM; i++){
21 | try {
22 | Socket s = new Socket();
23 | s.connect(new InetSocketAddress(sIp, sPort));
24 |
25 | if(false == s.isConnected()){
26 | System.out.println(" 连接 "+sIp+":"+sPort+" 失败! ");
27 | return;
28 | }
29 | sockets[i-1] = s;
30 |
31 | } catch (Exception e) {
32 | //连接失败则小憩一会儿接着连
33 | Thread.sleep(500);
34 | e.printStackTrace();
35 | }
36 |
37 | //稍稍停顿一下,避免把服务端的握手队列打满
38 | if(0 == i % 500){
39 | Thread.sleep(500);
40 | System.out.println("连接 "+sIp+":"+sPort+" 成功了 "+i+" 条");
41 | }
42 | }
43 |
44 | //把所有连接都 hold 一会儿,方便观察
45 | Thread.sleep(300 * 1000);
46 |
47 | //3. 释放所有的连接
48 | System.out.println("关闭所有的连接...\n");
49 | for(int i = 0; i < MAX_CONNECTION_NUM; i++){
50 | sockets[i].close();
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/tests/network/test03/java/Makefile:
--------------------------------------------------------------------------------
1 | CLIENT_BINARY_NAME := "java Client"
2 | SERVER_BINARY_NAME := "java Server"
3 |
4 | .PHONY: build-cli
5 | build-cli:
6 | javac Client.java
7 |
8 | .PHONY: run-cli
9 | run-cli: build-cli
10 | sh tool.sh runcli $(CLIENT_BINARY_NAME)
11 |
12 | .PHONY: stop-cli
13 | stop-cli:
14 | sh tool.sh stopcli
15 |
16 | .PHONY: build-srv
17 | build-srv:
18 | javac Server.java
19 |
20 | .PHONY: run-srv
21 | run-srv: build-srv
22 | sh tool.sh runsrv $(SERVER_BINARY_NAME)
23 |
24 | .PHONY: stop-srv
25 | stop-srv:
26 | sh tool.sh stopsrv
27 |
28 | .PHONY: clean
29 | clean:
30 | rm -f *.class
31 |
--------------------------------------------------------------------------------
/tests/network/test03/java/Server.java:
--------------------------------------------------------------------------------
1 | import java.io.IOException;
2 | import java.net.ServerSocket;
3 | import java.net.Socket;
4 | import java.net.InetSocketAddress;
5 |
6 | public class Server {
7 |
8 | public static final int MAX_CONNECTION_NUM = 1100000;
9 |
10 | public static void main(String[] args) {
11 | if(2 != args.length){
12 | System.out.println("Usage: java Server \n");
13 | return;
14 | }
15 |
16 | String sIp = args[0];
17 | int sPort = Integer.parseInt(args[1]);
18 |
19 | //用数组将 socket 保存起来,防止连接被过早回收
20 | Socket[] sockets = new Socket[MAX_CONNECTION_NUM];
21 |
22 | try {
23 | ServerSocket ss = new ServerSocket();
24 | ss.bind(new InetSocketAddress(sIp, sPort), 1024);
25 | System.out.println("启动Server " + sIp + ":" + sPort + "...");
26 |
27 | int i = 0;
28 | while(true){
29 | try{
30 | Socket s = ss.accept();
31 | sockets[i] = s;
32 | i++;
33 | System.out.println("Server " + sIp + ":" + sPort + " 接收到第 " + i +" 条连接!");
34 | } catch (IOException e) {
35 | e.printStackTrace();
36 | }
37 | }
38 | } catch (IOException e) {
39 | e.printStackTrace();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/tests/network/test03/java/tool.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #--------------------------- begin -------------------------
4 | #注意:这一部分的内容需要根据你自己的实验环境来设置
5 |
6 | #1.服务端的 IP
7 | #示例
8 | #SERVERIP="192.168.1.100"
9 | SERVERIP="192.168.1.100"
10 |
11 | #2.服务端的端口
12 | SERVERPORTS=(
13 | "8100"
14 | "8101"
15 | "8102"
16 | "8103"
17 | "8104"
18 | "8105"
19 | "8106"
20 | "8107"
21 | "8108"
22 | "8109"
23 | "8110"
24 | "8111"
25 | "8112"
26 | "8113"
27 | "8114"
28 | "8115"
29 | "8116"
30 | "8117"
31 | "8118"
32 | "8119"
33 | )
34 | #--------------------------- end -------------------------
35 |
36 | TYPE=$1
37 |
38 | exec_runcli(){
39 | for i in "${!SERVERPORTS[@]}"; do
40 | echo $CLIENT $SERVERIP ${SERVERPORTS[$i]} &
41 | $CLIENT $SERVERIP ${SERVERPORTS[$i]} &
42 | done
43 | }
44 |
45 | exec_stopcli(){
46 | ps -ef | grep java | grep Client | awk '{print $2}' | xargs kill -9
47 | }
48 |
49 | exec_runsrv(){
50 | for i in "${!SERVERPORTS[@]}"; do
51 | echo $SERVER 0.0.0.0 ${SERVERPORTS[$i]} &
52 | $SERVER 0.0.0.0 ${SERVERPORTS[$i]} &
53 | done
54 | }
55 |
56 | exec_stopsrv(){
57 | ps -ef | grep java | grep Server | awk '{print $2}' | xargs kill -9
58 | }
59 |
60 | case $TYPE in
61 | "runcli") CLIENT=$2; exec_runcli;;
62 | "stopcli") exec_stopcli;;
63 | "runsrv") SERVER=$2; exec_runsrv;;
64 | "stopsrv") exec_stopsrv;;
65 | *) echo "get unkown type $TYPE"; exit ;;
66 | esac
67 |
68 |
--------------------------------------------------------------------------------
/tests/network/test03/php/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: run-cli
2 | run-cli:
3 | sh tool.sh runcli
4 |
5 | .PHONY: stop-cli
6 | stop-cli:
7 | sh tool.sh stopcli
8 |
9 | .PHONY: run-srv
10 | run-srv:
11 | sh tool.sh runsrv
12 |
13 | .PHONY: stop-srv
14 | stop-srv:
15 | sh tool.sh stopsrv
16 |
--------------------------------------------------------------------------------
/tests/network/test03/php/client.php:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #define BUFFER_MAX 2048
10 |
11 | typedef int int32;
12 | typedef unsigned int u_int32;
13 | typedef unsigned char u_char;
14 | typedef unsigned short u_short;
15 |
16 | //参考内核 struct ethhdr 定义 (include/uapi/linux/if_ether.h)
17 | typedef struct eth_hdr {
18 | char h_dest[6];
19 | char h_source[6];
20 | short h_proto;
21 | }__attribute__((packed));
22 |
23 | //参考内核 struct iphdr 定义(include/uapi/linux/ip.h)
24 | typedef struct iphdr{
25 | #ifdef __LITTLE_ENDIAN_BIFIELD
26 | u_char ip_len:4, ip_ver:4;
27 | #else
28 | u_char ip_ver:4, ip_len:4;
29 | #endif
30 | u_char tos;
31 | u_short total_len;
32 | u_short id;
33 | u_short flags_off;
34 | u_char ttl;
35 | u_char protocol;
36 | u_short check;
37 | u_int32 saddr;
38 | u_int32 daddr;
39 | }__attribute__((packed));
40 |
41 | int main(int argc, char *argv[])
42 | {
43 | int sock;
44 | char buffer[BUFFER_MAX];
45 | int len;
46 |
47 | struct eth_hdr *mac_hdr;
48 | struct iphdr *ip_hdr;
49 | char* p;
50 |
51 | if( (sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0 ){
52 | printf("Create socket error.\n");
53 | exit(0);
54 | }
55 |
56 | while(1){
57 | len = recvfrom(sock, buffer, BUFFER_MAX, 0, NULL, NULL);
58 | if (len < 46) {
59 | printf("Catch packet length error.\n" );
60 | close(sock);
61 | exit(0);
62 | }
63 |
64 | printf("截获内容长度 %d\n", len);
65 |
66 | mac_hdr = buffer;
67 | ip_hdr = buffer + sizeof(struct ethhdr);
68 |
69 | printf("源 MAC:%X:%X:%X:%X:%X:%X",
70 | (u_char)mac_hdr->h_source[0],
71 | (u_char)mac_hdr->h_source[1],
72 | (u_char)mac_hdr->h_source[2],
73 | (u_char)mac_hdr->h_source[3],
74 | (u_char)mac_hdr->h_source[4],
75 | (u_char)mac_hdr->h_source[5]
76 | );
77 |
78 | printf(" ==> 目的 MAC:%X:%X:%X:%X:%X\n",
79 | (u_char)mac_hdr->h_dest[0],
80 | (u_char)mac_hdr->h_dest[1],
81 | (u_char)mac_hdr->h_dest[2],
82 | (u_char)mac_hdr->h_dest[3],
83 | (u_char)mac_hdr->h_dest[4],
84 | (u_char)mac_hdr->h_dest[5]
85 | );
86 |
87 | p = (char*)&ip_hdr->saddr;
88 | printf("源 IP: %d.%d.%d.%d",
89 | (u_char)p[0],
90 | (u_char)p[1],
91 | (u_char)p[2],
92 | (u_char)p[3]
93 | );
94 |
95 | p = (char*)&ip_hdr->daddr;
96 | printf(" ==> 目的 IP: %d.%d.%d.%d\n",
97 | (u_char)p[0],
98 | (u_char)p[1],
99 | (u_char)p[2],
100 | (u_char)p[3]
101 | );
102 |
103 | printf("协议类型:");
104 | switch(ip_hdr->protocol) {
105 | case IPPROTO_ICMP:
106 | printf("ICMP");
107 | break;
108 | case IPPROTO_IGMP:
109 | printf("IGMP");
110 | break;
111 | case IPPROTO_IPIP:
112 | printf("IPIP");
113 | break;
114 | case IPPROTO_TCP:
115 | printf("TCP");
116 | break;
117 | case IPPROTO_UDP:
118 | printf("UDP");
119 | break;
120 | case IPPROTO_RAW:
121 | printf("RAW");
122 | break;
123 | default:
124 | printf("Unknown type");
125 | break;
126 | }
127 |
128 | printf("\n\n");
129 | }
130 |
131 | close(sock);
132 | return 0;
133 | }
134 |
--------------------------------------------------------------------------------