支持多鏈接。git
Server運行以後,進入Accept阻塞狀態。Accept獲得一個Conn以後,開啓一個協程,分別有兩個協程阻塞在Read和Write。當Read一個數據以後,將Read獲得的數據寫入readChannel中,以後再對其進行處理。在writeChannel獲得一個數據以後,向Conn寫入數據。app
Client運行後,接入Server,以後開啓兩個協程阻塞在Read和Write的Channel中。在Scan獲得一個數據以後,向writeChannel寫入數據,喚醒阻塞的協程向Conn中寫入數據。當Server中有數據返回時,read協程被喚醒,將數據寫入readChannel中。socket
固然,還有諸多細節要處理。好比Conn的關閉在何時等等。tcp
客戶端源碼.net
package client import ( "net" "git.oschina.net/sdlszjb/unix_socket/errs" "fmt" ) func StartClient1() { tcpAddress, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:1300") if err != nil { errs.Error_exit(err) } conn, err := net.DialTCP("tcp", nil, tcpAddress) if err != nil { errs.Error_exit(err) } writeChan := make(chan []byte, 1024) readChan := make(chan []byte, 1024) go writeConnection(conn, writeChan) go readConnection(conn, readChan) //go handleReadChannel(readChan) for { var s string fmt.Scan(&s) writeChan <- []byte(s) } } func readConnection(conn *net.TCPConn, channel chan []byte) { defer conn.Close() buffer := make([]byte, 2048) for { n, err := conn.Read(buffer) if err != nil { errs.Error_print(err) return } println("Received from:", conn.RemoteAddr(), string(buffer[:n])) //channel <- buffer[:n] } } func writeConnection(conn *net.TCPConn, channel chan []byte) { defer conn.Close() for { select { case data := <- channel: _, err := conn.Write(data) if err != nil { errs.Error_exit(err) } println("Write to:", conn.RemoteAddr(), string(data)) } } }
服務端代碼:unix
package server import ( "net" "git.oschina.net/sdlszjb/unix_socket/errs" "fmt" ) var client_num int = 0 func StartServer1() { l, err := net.Listen("tcp", ":1300") if err != nil { errs.Error_exit(err) } defer l.Close() for { conn, err := l.Accept() if err != nil { errs.Error_print(err) continue } client_num++ fmt.Printf("A new Connection %d.\n", client_num) go handlerConnection(conn) } } func handlerConnection(conn net.Conn) { defer closeConnection(conn) readChannel := make(chan []byte, 1024) writeChannel := make(chan []byte, 1024) go readConnection(conn, readChannel) go writeConnection(conn, writeChannel) for { select { case data := <- readChannel: if string(data) == "bye" { return } writeChannel <- append([]byte("Back"), data...) } } } func writeConnection(conn net.Conn, channel chan []byte) { for { select { case data := <- channel: println("Write:", conn.RemoteAddr().String(), string(data)) _, err := conn.Write(data) if err != nil { errs.Error_print(err) return } } } } func readConnection(conn net.Conn, channel chan []byte) { buffer := make([]byte, 2048) for { n, err := conn.Read(buffer) if err != nil { errs.Error_print(err) channel <- []byte("bye") //這裏需要進一步改進! break } println("Recei:", conn.RemoteAddr().String(), string(buffer[:n])) channel <- buffer[:n] } } func closeConnection(conn net.Conn) { conn.Close() client_num-- fmt.Printf("Now, %d connections is alve.\n", client_num) }