After posix standard was introduced, socket has been well supported on all major OS platforms. Golang is a cross platform programming language with runtime. The socket API provided to developers in Go is based on the native socket interface of the operating system. But the behavior of socket interface in golang is different from that of native interface of operating system. In this paper, a simple hello/hi network chat program will be analyzed.
I. Introduction to socket
Firstly, the premise that processes can communicate with each other is that processes can be uniquely identified, and PID can be used for local communication. However, this method is not feasible in the network. We can uniquely identify a process through IP address + protocol + port number, and then use socket for communication.
socket is an abstract layer in the application layer and transport layer. It does not belong to the seven layer architecture:
The socket communication process is as follows:
1. Server creates socket
2. The server binds socket and port number
3. The server listens for the port number
4. The server starts accept() to receive the connection request from the client. If there is a connection, it will continue to execute. Otherwise, it will block here.
5. Client creates socket
6. The client connects to the server through IP address and port number, that is, three handshakes in tcp
7. If the connection is successful, the client can send data to the server
8. The server reads the data sent by the client
9. Any end can be disconnected actively
socket programming
With the abstract socket, when using the TCP or UDP protocol for web programming, you can do it in the following ways
Server pseudo code:
listenfd = socket(......)
bind(listenfd, ServerIp:Port, ......)
listen(listenfd, ......)
while(true) {
conn = accept(listenfd, ......)
receive(conn, ......)
send(conn, ......)
}
Client pseudocode:
clientfd = socket(......)
connect(clientfd, serverIp:Port, ......)
send(clientfd, data)
receive(clientfd, ......)
close(clientfd)
In the above pseudo code, listenfd is to realize the socket descriptor created by the server listening, and bind method is to use the port by the server process to avoid other ports being used by other processes. Listen method starts to listen to the port. The following while loop is used to process the client's endless requests. The accept method returns a conn, which is used to distinguish the connections of each client. The subsequent receiving and sending actions are based on this conn. In fact, accept is to complete the three handshakes of TCP with the client's connect.
3. socket in golang
golang provides some network programming API s, including Dial,Listen,Accept,Read,Write,Close, etc
3.1 Listen()
First, use the server net.Listen() method to create socket, bind port and listen port.
1 func Listen(network, address string) (Listener, error) { 2 var lc ListenConfig 3 return lc.Listen(context.Background(), network, address) 4 }
The above is the source code of Listen function provided by golang, where network represents network protocol, such as tcp,tcp4,tcp6,udp,udp4,udp6, etc. Address is the binding address. The Listener returned is actually a socket descriptor. Error stores the error information.
In Linux socket, socket,bind and listen functions are used to perform the same functions
// socket(Protocol domain, socket type, protocol) int socket(int domain, int type, int protocol); int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); int listen(int sockfd, int backlog);
3.2 Dial()
When the client wants to initiate more than one connection, it will use the net.Dial() method to initiate the connection
func Dial(network, address string) (Conn, error) { var d Dialer return d.Dial(network, address) }
Where network is the network protocol, and address is the address to establish the connection. The returned conn actually identifies each client. An interface of Conn is defined in golang:
type Conn interface { Read(b []byte) (n int, err error) Write(b []byte) (n int, err error) Close() error LocalAddr() Addr RemoteAddr() Addr SetDeadline(t time.Time) error SetReadDeadline(t time.Time) error SetWriteDeadline(t time.Time) error }type conn struct {