golang实现TCP网络编程

上一节简单介绍了TCP以及socket等基本理论,今天我们尝试用go分别从客户端和服务端对其实现。

golang实现服务端socket

package main

import (
    "net"
    "fmt"
)

func main() {
    fmt.Println("server has been start===>")
    tcpAddr, _ := net.ResolveTCPAddr("tcp",":8000") 
    //服务器端一般不定位具体的客户端套接字
    tcpListener, _ := net.ListenTCP("tcp",tcpAddr)

    ConnMap := make(map[string]*net.TCPConn)
    for{
        tcpConn, _ := tcpListener.AcceptTCP()
        defer tcpConn.Close()

        ConnMap[tcpConn.RemoteAddr().String()] = tcpConn
        fmt.Println("连接的客户端信息:",tcpConn.RemoteAddr().String())
    }
}

其中类型TCPConn是net包中定义的类型,它实现了conn接口,用来表示服务端与客户端的连接。

type TCPConn struct {
    conn
}

在任意时刻,计算机都可以有几条TCP连接处于打开状态,同样服务器也同时存在许多条TCP连接。从上一节内容可知,在client与server的通信之前,双方首先必须各自创建一个端点,否则是没有办法建立联系并相互通信的。go中用TCPAddr来表示端点。

type TCPAddr struct {
    IP   IP
    Port int
    Zone string // IPv6 scoped addressing zone
}

go语言中可以通过方法ResolveTCPAddr(network, address string) (*TCPAddr, error) 来获得TCPAddr。参数network用来指定网络类型,可接受的参数为tcp、tcp4、tcp6,分别表示IP v4、IP v6和任意。
接下来就是设置允许套接字进行连接(listen)和等待连接(accept)。

golang实现客户端socket

package main

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

var ch = make(chan int)

func main() {
    tcpAddr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:8000")
    conn, err := net.DialTCP("tcp", nil, tcpAddr)
    if err != nil {
        fmt.Println("server is not starting")
        return
    }

    defer conn.Close()

    for {
        inputReader := bufio.NewReader(os.Stdin)
        input, err := inputReader.ReadString('\n')
        if err == nil {
            fmt.Printf("client send:%s", input)
        }
        //将从输入中读取的内容写入到连接中
        b := []byte(input)
        conn.Write(b)

        select {
        case <-ch:   
            fmt.Println("server error,please reconnecting")
            return
        default:
            //不加default的话,那么<-ch会阻塞for,下一个输入就没法进行
        }
    }
}

client实现比服务端简单一点,不用监听等一系列动作,只需要设置好socket,进行连接就可以。go中方法DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error)可以用来连接指定的socket。参数laddr为nil时,系统会自动选择一个socket作为client的TCPAddr。参数raddr为要连接的TCPAddr。如果连接成功,方法会返回一个TCPConn连接。
在连接成功后,就可以使用下面两种方法对数据进行读写。

func (c *conn) Write(b []byte) (int, error) {}
func (c *conn) Read(b []byte) (int, error) {}

由于conn实现了Write和Read接口,因此可以在TCPConn上,直接调用这两种方法。

你可能感兴趣的:(HTTP学习总结)