• 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发送信息
    ", c.RemoteAddr().String())
    		buf := make([]byte, 1024)
    		n, err := c.Read(buf)
    		if err != nil {
    			fmt.Printf("读取数据失败,%v
    ", err)
    			return
    		}
    		fmt.Printf("读取字节数为%d
    ", 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
    ", err)
    	}
    	reader := bufio.NewReader(os.Stdin) //os.Stdin 代表标准输入[终端]
    	for {
    		line, err := reader.ReadString('
    ')
    		if err != nil {
    			fmt.Println("读取终端数据错误")
    			return
    		}
    		line = strings.Trim(line, "
    ")
    		if line == "exit" {
    			fmt.Println("用户退出客户端")
    			break
    		}
    		conent, err := conn.Write([]byte(line + "
    "))
    		if err != nil {
    			log.Fatal(err)
    		}
    		fmt.Printf("客户端发送了 %d 字节的数据到服务端
    ", conent)
    	}
    }
    
    func main() {
    	Client()
    }
    
    
  • 相关阅读:
    Poj 2104 K-th Number(主席树&&整体二分)
    Bzoj 3262: 陌上花开(CDQ分治)
    Bzoj 2683: 简单题(CDQ分治)
    ZOJ2314 Reactor Cooling(无源汇上下界可行流)
    Cogs 12. 运输问题2(有上下界的有源汇最大流)
    Cogs 461. [网络流24题] 餐巾(费用流)
    Codevs 1227 方格取数 2(费用流)
    Cogs 13. 运输问题4(费用流)
    Poj 2195 Going Home(费用流)
    开学第二测
  • 原文地址:https://www.cnblogs.com/heych/p/12579623.html
Copyright © 2020-2023  润新知