支持多链接。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) }