受限于本地端口数的分配,我想看看本地能起到多少个TCP client连接
本测试用例client和server都部署在同一台linux虚拟机上
查看进程打开的描述符数:102400(10万)
[root@bogon ~]# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 15042 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 102400 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 15042 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
再看看测试代码,client端:
package main import ( _ "bytes" "fmt" "net" "net/url" _ "os" "strconv" "time" ) var ( DefalutTimeout = 25 * time.Second MaxClient = 70000 clientNum = 0 msg_nums = 0 ) func sockConn(daemon string, timeout time.Duration) (net.Conn, error) { daemonURL, err := url.Parse(daemon) //fmt.Printf("daemon url %v %v \n", daemonURL, daemonURL.Scheme) if err != nil { return nil, fmt.Errorf("could not parse url %q: %v", daemon, err) } var c net.Conn switch daemonURL.Scheme { case "unix": return net.DialTimeout(daemonURL.Scheme, daemonURL.Path, timeout) case "tcp": return net.DialTimeout(daemonURL.Scheme, daemonURL.Host, timeout) default: return c, fmt.Errorf("unknown scheme %v (%s)", daemonURL.Scheme, daemon) } } func sendData(socket net.Conn, n int, msg_num_chan chan int) { buf := make([]byte, 10) for { _, err := socket.Write([]byte(strconv.Itoa(n))) if err != nil { fmt.Printf("Error reading:%s\n", err.Error()) clientNum-- return } //send reply _, err = socket.Read(buf) fmt.Printf("client %v\n", string(buf)) if err != nil { fmt.Printf("Error send reply:%s\n", err.Error()) clientNum-- return } //time.Sleep(1 * time.Second) msg_num_chan <- 1 buf = buf[0:] } } func connectServer(msg_num_chan chan int) { for i := 1; i <= MaxClient; i++ { socket, err := sockConn("tcp://127.0.0.1:8088", DefalutTimeout) if err != nil { fmt.Printf("connect error:%s\n", err) } else { clientNum++ go sendData(socket, i, msg_num_chan) } } } func main() { msg_num_chan := make(chan int) connectServer(msg_num_chan) go func() { for msg_num := range msg_num_chan { msg_nums += msg_num } }() time.Sleep(10 * time.Second) fmt.Printf("rec msg %d \n", msg_nums) }
Server端:
package main import ( "fmt" "net" "os" "time" ) const ( MAX_CONN_NUM = 100000 ) func EchoFunc(conn net.Conn) { defer conn.Close() buf := make([]byte, 10) for { _, err := conn.Read(buf) if err != nil { //println("Error reading:", err.Error()) return } //fmt.Printf("server %s\n", string(buf)) //send reply _, err = conn.Write(buf) if err != nil { //println("Error send reply:", err.Error()) return } } } func main() { listener, err := net.Listen("tcp", "127.0.0.1:8088") if err != nil { fmt.Println("error listening:", err.Error()) os.Exit(1) } defer listener.Close() fmt.Printf("running ...\n") var cur_conn_num int = 0 conn_chan := make(chan net.Conn) ch_conn_change := make(chan int) go func() { for conn_change := range ch_conn_change { cur_conn_num += conn_change } }() go func() { for _ = range time.Tick(5e9) { fmt.Printf("cur conn num: %d\n", cur_conn_num) } }() for i := 0; i < MAX_CONN_NUM; i++ { go func() { for conn := range conn_chan { ch_conn_change <- 1 EchoFunc(conn) ch_conn_change <- -1 } }() } for { conn, err := listener.Accept() if err != nil { println("Error accept:", err.Error()) return } conn_chan <- conn } }
最后看看server端执行结果:
[root@bogon mpro]# go run server.go running ... cur conn num: 0 cur conn num: 17452 cur conn num: 28233 cur conn num: 28233 cur conn num: 28233 ^C^Cexit status 2
client端执行结果:
connect error:dial tcp 127.0.0.1:8088: cannot assign requested address connect error:dial tcp 127.0.0.1:8088: cannot assign requested address connect error:dial tcp 127.0.0.1:8088: cannot assign requested address connect error:dial tcp 127.0.0.1:8088: cannot assign requested address connect error:dial tcp 127.0.0.1:8088: cannot assign requested address connect error:dial tcp 127.0.0.1:8088: cannot assign requested address
只能起到2万8个连接,最主要受限于端口数
本例只是测试client端的连接数,不是测试server的连接数
有疑问加站长微信联系(非本文作者)