Objective
See the Teacher's section on the Goroutine and channel of the lecture class, the feeling is not very clear, so decided to implement a chat room function
Why is it a group chat?
Because group chat is relatively logical.
Note: This chestnut only uses the goroutine and does not use the channel
Overview
1. The composition of the chat room
The chat room is divided into two sections, namely:
Then, in general, we chat with each other is only the client , the server is just the role of scheduling
2. The process of sending and receiving information
Suppose we have 服务端(S) 客户端(C1) 客户端(C2)客户端(C3)
and S has established a connection with C1 C2 C3
The theoretical process is this:
- C1 sends a message to S
- S received message
- S Broadcast the received information to C2 C3
- C2 C3 Receiving information
Practice
1. Service-side
1) Code
Package Mainimport ("Time" "FMT" "NET")//client map var Client_map = make (map[string]*net. Tcpconn)//Listener request Func listen_client (Ip_port string) {tcpaddr, _: = Net. RESOLVETCPADDR ("TCP", Ip_port) TcpListener, _: = Net. LISTENTCP ("TCP", tcpaddr) for {///non-stop receiving Client_con, _: = Tcplistener.accepttcp ()//Listener Request Connection Client_map[clie Nt_con. Remoteaddr (). String ()] = client_con//Adds the connection to the map Go add_receiver (client_con) fmt. Println ("User:", Client_con. Remoteaddr (). String (), "connected.") }}//adds the receiver func add_receiver (Current_connect *net) to the connection. Tcpconn) {for {byte_msg: = make ([]byte, 2048) len, err: = Current_connect. Read (byte_msg) if err! = Nil {current_connect. Close ()} FMT. Println (String (Byte_msg[:len))) Msg_broadcast (Byte_msg[:len], current_connect. Remoteaddr (). String ())}}//broadcast to all Clientfunc Msg_broadcast (byte_msg []byte, key String) {for k, con: = Range Client_map { If k! = key {con. Write (byte_msg)}}}//The main function, Func, main () {FMT. PRINTLN ("service started ...") time. Sleep (1 * time. Second) fmt. Println ("Waiting for client to request connection ...") Go listen_client ("127.0.0.1:1801") select{}}
b) Description
As you can see, aside from the main function, there are altogether 2 routine, namely:
- Listening to connections
- Receive messages (broadcast messages are here too)
2. Client
A) code
Package Mainimport ("FMT" "NET" "OS" "Bufio")//user name Var login_name string//native connection var self_connect *n Et. tcpconn//read line text var reader = Bufio. Newreader (OS. Stdin)//Establish connection func connect (addr string) {tcp_addr, _: = Net. RESOLVETCPADDR ("tcp", addr)//Using TCP con, err: = Net. DIALTCP ("TCP", nil, TCP_ADDR)//dial Self_connect = con if err! = Nil {fmt. PRINTLN ("Server Connection Failed") OS. Exit (1)} go Msg_sender () go msg_receiver ()}//message receiver Func msg_receiver () {buff: = make ([]byte, 2048) for { Len, _: = Self_connect. Read (Buff)//reads the message FMT. Println (String (Buff[:len)))}}//message sender func Msg_sender () {for {read_line_msg, _, _: = Reader. ReadLine () read_line_msg = []byte (login_name + ":" + string (read_line_msg)) Self_connect. Write (read_line_msg)}}//main function func main () {FMT. Println ("What would you call it?") ") Name, _, _: = Reader. ReadLine () login_name = string (name) connect ("127.0.0.1:1801") select{}}
b) Description
Similarly, the client is also composed of two routine :
- Message Receivers
- Message Transmitters
Establish the connection in the main thread complete
3.
A) service-side
b) Client _1
c) Client _2
End
The channel is not used here.
The little chestnut is only for the experience summary, the study exchange and the record