您的位置:首页 > 编程语言

[Golang]Socket编程01----实现基本功能的Client和Server

2017-01-13 00:00 253 查看
支持多连接。

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)

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  golang socket