First, pre-preparation
- Pre-preparation
- Import "NET" package required
- IP type, one of the important methods is IP. Parseip (IPAddr string) to determine if it is a legitimate IP address
- TCP Client
func (c *TCPConn) Write(b []byte) (n int, err os.Error)
Used to send data, return the length of data sent or return an error, is the method of Tcpconn
func (c *TCPConn) Read(b []byte) (n int, err os.Error)
Used to receive data, return the received length or return an error, is the method of Tcpconn
- TCPADDR type, which holds address information for TCP, including address and port
struct { IP ip int }
-
func resolvetcpaddr (NET, addr string) (*tcpaddr, OS. Error)
gets a tcpaddr, parameters are of type string, net is a const string, including TCP4,TCP6,TCP generally uses TCP, compatible V4 and v6,addr represent IP addresses, including port numbers, such as www . google.com:80 such as
-
func dialtcp (net string, laddr, Raddr *tcpaddr) (c *tcpconn, err OS. Error)
is used to connect (connect) to the remote server, net means the protocol, TCP,TCP4 or tcp6,laddr represents the native address, typically NIL,RADDR represents the remote address, where the laddr and raddr are TCPA DDR type, which is typically the return value of the previous function.
- as a client of TCP, the basic operating procedure is as follows:
service= " www.google.com:80 " tcpaddr, err: = net. RESOLVETCPADDR ( " TCP4 " , service) conn, err: = net. Dialtcp ( " tcp " = conn. Write ([]byte ( " head/http/1.0\r\n\r\n " = conn. Read (b)/result, err: = Ioutil. ReadAll (conn)
- TCP Server
-
func listentcp (net string, Laddr *tcpaddr) (l *tcplistener, err os. Error)
is used to listen on the port, net represents the protocol type, LADDR represents the native address, is the TCPADDR type, note that laddr here include the port, return a *tcplistener type or error
-
func (l *tcplistener) Accept () (c Conn, err OS. Error)
is used to return a new connection for subsequent operations, which is a TcpListener method, generally TcpListener returned from the previous function. The basic operating procedure for the
- server is:
service:=": 9090" tcpaddr, err:= net. Resolvetcpaddr ("tcp4", Service) l,err:= net. Listentcp ("tcp", Tcpaddr) conn,err:= l.accept () // Use the GO keyword here to create a new thread-processing connection to implement concurrency
Second, chat room requirements
Implement a public chat server.
- server receives client-side information
- Sends the client's information to all clients after it has been received
- Client uses
/quit
exit Chat
- Use only one set of code to start a server or client with command-line arguments
The main points of knowledge are as follows:
The code includes the server and client content, if it is a server, directly input go run Main.go server 9090
can, the client is also very simple, enter go run Main.go client :9090
is good;
If it is a client, it includes two parts, part is the Chatsend function, accept the user's input, the other part is connect to the server, accept the relevant information;
If it's a server, it's a little more complicated, with three parts. The first part is to constantly accept the client; the second is to create a Handler function for each client, accept the information sent by the client, and the third is the Echohandler function, which is to broadcast the information received from one user to all other clients. It's that simple.
Code implementation:
Package Mainimport ("OS" "FMT" "Net")/** Main program start client and server parameter description: Start the servers: Go run Main.go server [port] eg:go run Main.go server 9090 start client: Go ru n main.go [Server Ip addr]:[server Port] eg:go run main.go client:9090*/Func Main () {ifLen (OS. Args)! =3{fmt. Println ("wrong params") OS. Exit (0) } ifOs. args[1] =="Server"{startserver (OS). args[2]) } ifOs. args[1] =="Client"{startclient (OS). args[2]) }}/** Start Server parameter: Port port number*/func startserver (Portstring) {service:=":"+Port Tcpaddr,err:= Net. RESOLVETCPADDR ("TCP4", Service) checkerror (err,"resolvetcpaddr") L,err:= Net. LISTENTCP ("TCP", TCPADDR) checkerror (err,"listentcp") Conns:= Make (map[string]net. Conn) messages:= Make (chanstring,Ten) //Start Server Broadcast thread: Send messages to all clientsGo Echohandler (&Conns, messages) for{fmt. Println ("Listening ...") Conn,err:= L.accept ()//returns a new connectionCheckError (Err,"l.accept") fmt. Println ("Accepting ...") Conns[conn. Remoteaddr (). String ()]=Conn//initiates a thread that accepts a client sending a messageGo Handler (conn, messages)}}/** The server sends the data thread: Send message parameters to all clients connection dictionary Conns data channel messages*/func Echohandler (Conns*map[string]net. Conn, Messages Chanstring) { for{msg:= <-messages FMT. PRINTLN (msg) forKey,con: = range *Conns {fmt. Println ("connection is connected from ...", key) _,err:= Con. Write ([]byte(msg))ifErr! =Nil {fmt. PRINTLN (Err) Delete (*Conns, Key)} } }}/** Server-side receive client data thread parameters: According to the connection conn communication channel messages*/func Handler (conn net. Conn, Messages Chanstring) {fmt. Println ("connection is connected from ...", Conn. Remoteaddr (). String ()) BUF:= Make ([]byte,1024x768) for{lenght,err:=Conn. Read (BUF)ifCheckError (Err,"Connection") ==false{Conn. Close () Break } ifLenght >0{Buf[lenght]=0} RECIVESTR:=string(buf[0: Lenght]) Messages<-Recivestr}}/** Client Startup function Parameters: Process IP address and port tcpaddr*/func startclient (tcpaddrstring) {tcpaddr,err:= Net. RESOLVETCPADDR ("TCP4", TCPADDR) checkerror (err,"resolvetcpaddr") Conn,err:= Net. DIALTCP ("TCP", NIL,TCPADDR) checkerror (err,"dialtcp") //To start the client send data threadgo chatsend (conn)//messages sent by the receiving serverBUF: = make ([]byte,1024x768) for{lenght,err:=Conn. Read (BUF)ifCheckError (Err,"Connection") ==false{Conn. Close () fmt. Println ("Server is dead ... Byebye") OS. Exit (0)} FMT. Println (string(buf[0: Lenght])) }}/** Client send data thread parameter: Send Connection conn*/func chatsend (conn net. Conn) {varInputstringUsername:=Conn. Localaddr (). String () for{fmt. SCANLN (&input)ifinput = ="/quit"{fmt. Println ("Byebye .") Conn. Close () OS. Exit (0)} Lens,err:= Conn. Write ([]byte(Username +"say :::"+input)) Fmt. PRINTLN (Lens)ifErr! =Nil {fmt. Println (Err. Error ()) Conn. Close () Break } }}//error MessageFunc checkerror (err error, infostring) (resBOOL) { ifErr! =Nil {fmt. PRINTLN (Info+", err:"+Err. Error ())return false } return true}