支持多连接。
Server运行之后,进入Accept阻塞状态。Accept得到一个Conn之后,开启一个协程,分别有两个协程阻塞在Read和Write。当Read一个数据之后,将Read得到的数据写入readChannel中,之后再对其进行处理。在writeChannel得到一个数据之后,向Conn写入数据。
Client运行后,接入Server,之后开启两个协程阻塞在Read和Write的Channel中。在Scan得到一个数据之后,向writeChannel写入数据,唤醒阻塞的协程向Conn中写入数据。当Server中有数据返回时,read协程被唤醒,将数据写入readChannel中。
当然,还有诸多细节要处理。比如Conn的关闭在什么时候等等。
客户端源码
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))
}
}
}
服务端代码:
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)
}
有疑问加站长微信联系(非本文作者)