Go语言之Go语言网络编程

GO 语言网络编程

Go 语言Socket编程

TCP Socket

Go语言的 net 包中有一个 TCPConn 类型,可以用来建立 TCP 客户端和 TCP 服务器端间的通信通道,TCPConn 类型里有两个主要的函数:

func (c *TCPConn) Write(b []byte) (n int, err os.Error)
func (c *TCPConn) Read(b []byte) (n int, err os.Error)

CPConn 可以用在客户端和服务器端来读写数据。

还有我们需要知道一个 TCPAddr 类型,它表示一个 TCP 的地址信息,其定义如下:

type TCPAddr struct {
    IP IP
    Port int
}

在Go语言中通过 ResolveTCPAddr 可以获取一个 TCPAddr 类型,ResolveTCPAddr 的函数定义如下:

func ResolveTCPAddr(net, addr string) (*TCPAddr, os.Error)

参数说明如下:

  • net 参数是 "tcp4"、"tcp6"、"tcp" 中的任意一个,分别表示 TCP(IPv4-only),TCP(IPv6-only) 或者 TCP(IPv4,IPv6) 中的任意一个;
  • addr 表示域名或者 IP 地址,例如 "c.biancheng.net:80" 或者 "127.0.0.1:22"。

TCP server

我们可以通过 net 包来创建一个服务器端程序,在服务器端我们需要绑定服务到指定的非激活端口,并监听此端口,当有客户端请求到达的时候可以接收到来自客户端连接的请求。

net 包中有相应功能的函数,函数定义如下

func ListenTCP(net string, laddr *TCPAddr) (l *TCPListener, err os.Error)
func (l *TCPListener) Accept() (c Conn, err os.Error)

ListenTCP 函数会在本地 TCP 地址 laddr 上声明并返回一个 *TCPListener,net 参数必须是 "tcp"、"tcp4"、"tcp6",如果 laddr 的端口字段为 0,函数将选择一个当前可用的端口,可以用 Listener 的 Addr 方法获得该端口。

案列:

server

package main

import (
	"fmt"
	"net"
)

func echo(c *net.TCPConn) {
	defer c.Close()
	for {
		fmt.Printf("服务器再等待客户端%s发送信息\n", c.RemoteAddr().String())
		buf := make([]byte, 1024)
		n, err := c.Read(buf)
		if err != nil {
			fmt.Printf("读取数据失败,%v\n", err)
			return
		}
		fmt.Printf("读取字节数为%d\n", n)
		fmt.Printf(string(buf[:n]))
	}
}

// Server 表示服务器端函数
func Server() {
	address := net.TCPAddr{
		IP:   net.ParseIP("127.0.0.1"),
		Port: 8000,
	}
	listener, err := net.ListenTCP("tcp4", &address)
	if err != nil {
		fmt.Println("错误")
	}
	defer listener.Close()
	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			fmt.Println("报错")
		}
		fmt.Printf("客户端ip地址为:%v ", conn.RemoteAddr().String())
		go echo(conn)
	}

}

func main() {
	Server()
}

client

package main

import (
	"bufio"
	"fmt"
	"log"
	"net"
	"os"
	"strings"
)

// Client 表示客户端函数
func Client() {
	conn, err := net.Dial("tcp4", "127.0.0.1:8000")
	if err != nil {
		fmt.Printf("错误  %v\n", err)
	}
	reader := bufio.NewReader(os.Stdin) //os.Stdin 代表标准输入[终端]
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("读取终端数据错误")
			return
		}
		line = strings.Trim(line, "\r\n")
		if line == "exit" {
			fmt.Println("用户退出客户端")
			break
		}
		conent, err := conn.Write([]byte(line + "\n"))
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("客户端发送了 %d 字节的数据到服务端\n", conent)
	}
}

func main() {
	Client()
}

猜你喜欢

转载自www.cnblogs.com/heych/p/12579623.html