最大連接數“65535”的誤解


編程模型

讓我們先看一下socket的編程模型:

以上圖片來自此文

和C語言不同的是,go語言在底層幫我們封裝了socket,ListenTCP的時候創建,綁定,並監聽;DialTCP的時候,創建並連接 。具體可以看此文,或者用調試模式跟蹤一下。下面讓我們用代碼來看清服務器只能有65536個最大鏈接的謬論吧。

服務端代碼

server.go

package main

import (
	"fmt"
	"net"
	"os"
)

func main() {
	if len(os.Args) != 2 {
		fmt.Printf("Usage: %s host:port\n", os.Args[0])
		return
	}

	//創建TCP協議
	tcpAddr, err := net.ResolveTCPAddr("tcp4", os.Args[1]) //tcp4 是協議版本,還有tcp6 如果只有端口的話默認綁定127.0.0.1
	checkError(err)

	//創建、綁定、監聽socket
	listener, err := net.ListenTCP("tcp4", tcpAddr)
	checkError(err)
	for {
		//等待連接
		conn, err := listener.Accept()
		if err != nil {
			continue
		}
		//處理連接
		go handleClient(conn)
	}
}

func handleClient(conn net.Conn) {
	defer conn.Close()
	fmt.Printf("client address %s\n",conn.RemoteAddr().String())
	conn.Write([]byte(`hello`))
}

func checkError(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Fatal error: %s\n", err.Error())
		os.Exit(1)
	}
}

客戶端代碼

package main

import (
	"fmt"
	"net"
	"os"
	"time"
)

func main() {
	if len(os.Args) != 2 {
		fmt.Print( "Usage: %s host:port \n", os.Args[0])
		return
	}

	tcpAddr, err := net.ResolveTCPAddr("tcp4", os.Args[1])
	checkError(err)
	//創建socket並連接服務器
	conn, err := net.DialTCP("tcp4", nil, tcpAddr)
	checkError(err)
	fmt.Printf("client address %s\n",conn.LocalAddr().String())

	defer conn.Close()
	var buf [512]byte
	for {
		//從服務器讀取數據
		n, err := conn.Read(buf[0:])
		if n == 0 {
			time.Sleep(time.Second)  //如果沒讀到就繼續等待
			continue
		}
		checkError(err)
		fmt.Printf("receive %s from server\n",string(buf[0:n]))

	}


}
func checkError(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Fatal error: %s\n", err.Error())
		os.Exit(1)
	}
}

測試鏈接

需要兩台電腦測試,這里使用虛擬機

啟動服務端

go run server.go 0.0.0.0:7777 ,這里在虛擬機上運行服務端
這里0.0.0.0 的意思是允許來自外部的鏈接

啟動客戶端

go run client.go 服務端ip地址:7777,這里在本地運行客戶端,並啟動了四個

查看端口

服務端

客戶端

從上圖我們可以看到:

  • 客戶端連接到服務端后,服務端隨機分配了一個端口給客戶端,客戶端會綁定分配自己的端口。
  • 對客戶端來說7777這個端口,並沒有綁定,否則我們也不能啟動多個客戶端了。7777這個端口對客戶端來說,就是連接服務端的坐標。
  • 再看服務端,分配給客戶端后建立連接后,也沒有綁定分配的那個端口,比如上圖的43718。

誤解從何而來

看一下socket的編程模型,我估計在與服務端的accept這個環節。其實這個環節並沒有另外去綁定一個端口來和客戶端通信。
擴展一下,其實對於服務端來說,端口數並不能限制(因為只綁定一個端口),那么連接客戶端的總數限制就在於內存、CPU和網絡帶寬了。
對於客戶端呢,連接同一個服務端時,都要占用一個端口,對同一台電腦,限制可以運行的客戶端總數就在於端口數、內存、CPU和網絡帶寬。
另外65535這個數目實際上是可以更改的。

推薦工具

這里的虛擬機使用的vagrant,一個方便的虛擬機管理軟件,


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM