programming model
Let's take a look at the programming model of socket first: the
above picture is from this article
Different from the C language, the go language helps us encapsulate the socket at the bottom layer. When ListenTCP creates, binds, and listens; when DialTCP, creates and connects. For details, see this article , or trace it in debug mode. Let's use the code to clear the myth that the server can only have 65536 maximum links.
server code
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)
}
}
client code
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)
}
}
test link
Two computers are required for testing, here a virtual machine is used
Start the server
go run server.go 0.0.0.0:7777 , here runs the server on a virtual machine
Here 0.0.0.0 means to allow links from outside
start the client
go run client.go server ip address: 7777, where the client is run locally and four are started
view port
Server
client
From the above figure we can see:
- After the client connects to the server, the server randomly assigns a port to the client, and the client binds and assigns its own port.
- For the client, the port 7777 is not bound, otherwise we will not be able to start multiple clients. For the client, the port 7777 is the coordinate for connecting to the server.
- Looking at the server, after the connection is established after being assigned to the client, the assigned port is not bound, such as 43718 in the figure above.
Where does misunderstanding come from
Looking at the programming model of socket, I estimate that it is in the link of accept with the server. In fact, this link does not bind another port to communicate with the client.
To expand, in fact, for the server, the number of ports cannot be limited (because only one port is bound), then the total number of connected clients is limited by memory, CPU and network bandwidth.
For the client, when connecting to the same server, one port is occupied. For the same computer, the total number of clients that can be run is limited by the number of ports, memory, CPU and network bandwidth.
In addition, the number of 65535 can actually be changed.
Recommended tools
The virtual machine here uses vagrant, a convenient virtual machine management software,