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

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

}
相关文章
相关标签/搜索