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

前端之家收集整理的这篇文章主要介绍了[Golang]Socket编程01----实现基本功能的Client和Server前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

支持多连接。

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:",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:",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)

}

猜你在找的Go相关文章