• net包之TCPConn


    • FD file descriptor 文件信息
    • netFD 实现了各个系统对socket的封装

    conn

    该结构实现了Conn接口

    type conn struct {
    	fd *netFD
    }
    

    conn的方法

    Read(b []byte) (n int, err error)
    从连接中读取所有内容
    			result, err := ioutil.ReadAll(conn)  //读取所有内容
    			
    			//读取指定长度的内容
    			var buf [512]byte
    			n, err := conn.Read(buf[0:])
    
    			//不断的从连接读取..
    			result := bytes.NewBuffer(nil)
    			var buf [512]byte
    			for {
    			        n, err := conn.Read(buf[0:])
    			        result.Write(buf[0:n])
    			        if err != nil {
    			                if err == io.EOF {
    			                        break
    			                }
    			                return nil, err
    			        }
    			}
    			return result.Bytes(), nil
    		
    Write(b []byte) (n int, err error)
    向连接中写入数据,n是写入数据的大小
    			_, err = conn.Write([]byte("GET / HTTP/1.0\r\n\r\n"))		
    		
    Close() error
    关闭连接
    LocalAddr() Addr
    获取发送连接的本地IP和端口
    RemoteAddr() Addr
    获取目标主机的ip和端口
    			tcpAddr, err := net.ResolveTCPAddr("tcp4", "www.baidu.com:80")
    			conn, err := net.DialTCP("tcp", nil, tcpAddr)
    			fmt.Println(conn.LocalAddr())    //	192.168.1.88:51164
    			fmt.Println(conn.RemoteAddr())   //	220.181.111.147:80
    		
    SetDeadline(t time.Time) error
    设置连接到期时间,就是连接超时时间
    SetReadDeadline(t time.Time) error
    设置连接读取到期时间
    SetWriteDeadline(t time.Time) error
    设置连接写入到期时间
    SetReadBuffer(bytes int) error
    设置操作系统连接相关接收缓冲区大小
    SetWriteBuffer(bytes int) error
    设置操作系统连接相关传输缓冲区大小
    File() (f *os.File, err error)
    返回网络文件信息

    TCPConn

    注意:该类型并没有实现PacketConn接口.这是和udp的不同

    type TCPConn struct {
    	conn
    }
    

    DialTCP

    一旦客户端已经建立TCP服务, 就可以和对方设备"通话"了. 如果成功,该调用返回一个用于通信的TCPConn。客户端和服务器通过它交换消息。通常情况下,客户端使用TCPConn写入请求到服务器, 并从TCPConn的读取响应。持续如此,直到任一(或两者)的两侧关闭连接。客户端使用DialTCP()该函数建立一个TCP连接。

    	DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error)
    

    其中laddr是本地地址,通常设置为nil;raddr是一个服务的远程地址, net是一个字符串,根据您是否希望是一个TCPv4连接,TCPv6连接来设置为"tcp4", "tcp6"或"tcp"中的一个,当然你也可以不关心链接形式。

    客户端可能发送的消息之一就是“HEAD”消息。这用来查询服务器的信息和文档信息。 服务器返回的信息,不返回文档本身。发送到服务器的请求可能是:

    	"HEAD / HTTP/1.1\r\n\r\n"
    

    来吧看一个完整的栗子:

    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    	"net"
    	"os"
    )
    
    func main() {
    	tcpAddr, err := net.ResolveTCPAddr("tcp4", "localhost:80")  //换成www.baidu.com:80试一试
    	checkError(err)
    
    	conn, err := net.DialTCP("tcp", nil, tcpAddr)
    	checkError(err)
    
    	_, err = conn.Write([]byte("GET / HTTP/1.0\r\n\r\n"))  //发送http请求
    	checkError(err)
    
    	result, err := ioutil.ReadAll(conn)
    	checkError(err)
    
    	fmt.Println(string(result))
    
    	os.Exit(0)
    }
    
    func checkError(err error) {
    	if err != nil {
    		fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
    		os.Exit(1)
    	}
    }
    

    TCPConn的方法

    ReadFrom(r io.Reader) (int64, error)
    从一个IO中读取数据
    CloseRead() error
    CloseWrite() error
    SetLinger(sec int) error
    SetKeepAlive(keepalive bool) error
    即使没有任何通信,一个客户端可能希望保持连接到服务器的状态。
    SetNoDelay(noDelay bool) error
    设置操作系统是否延迟发送数据包,默认是无延迟的

    TCPlistener

    type TCPListener struct {
    	fd *netFD
    }
    

    ListenTCP

    在一个服务器上注册并监听一个端口。然后它阻塞在一个"accept"操作,并等待客户端连接。当一个客户端连接, accept调用返回一个连接(connection)对象

    net参数可以设置为字符串"tcp", "tcp4"或者"tcp6"中的一个。如果你想监听所有网络接口,IP地址应设置为0,或如果你只是想监听一个简单网络接口,IP地址可以设置为该网络的地址。如果端口设置为0,O/S会为你选择一个端口。否则,你可以选择你自己的。需要注意的是,在Unix系统上,除非你是监控系统,否则不能监听低于1024的端口,小于128的端口是由IETF标准化。该示例程序选择端口1200没有特别的原因。TCP地址如下":1200"

    让我们看个完整的栗子

    package main
    
    import (
    	"fmt"
    	"net"
    	"os"
    	"time"
    )
    
    func main() {
    	tcpAddr, err := net.ResolveTCPAddr("tcp", ":1201")
    	checkError(err)
    
    	listener, err := net.ListenTCP("tcp", tcpAddr)
    	checkError(err)
    
    	for {
    		conn, err := listener.Accept()
    		if err != nil {
    			continue
    		}
    		daytime := time.Now().String()
    		conn.Write([]byte(daytime))
    		conn.Close()
    	}
    }
    
    func checkError(err error) {
    	if err != nil {
    		fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
    		os.Exit(1)
    	}
    }
    	
    

    相比客户端服务器更要注意对错误的处理。服务器应该永远运行,所以,如果出现任何错误与客户端,服务器只是忽略客户端继续运行。否则,客户端可以尝试搞砸了与服务器的连接,并导致服务器宕机。

    TCPListener方法

    AcceptTCP() (c *TCPConn, err error)
    接收TCP连接
    Accept() (c Conn, err error)
    接收,返回一个连接
    Close() error
    关闭监听
    Addr() Addr
    返回监听的网络地址
    SetDeadline(t time.Time) error
    设置监听到期时间
    			listener.SetDeadline(time.Now().Add(time.Second * 30))
    		
    File() (f *os.File, err error)

    关于长连接理论上的实现.

    长连接,就是不断的连接.只要保证连接不断.服务端不断循环读取连接中的值,然后进行处理.发送结果就OK了.保持连接..发送.接受.

  • 相关阅读:
    请使用支持 JDBC 4.0 的 sqljdbc4.jar 类库
    add jars和add external jars有什么区别
    JDBC连接sql server数据库的详细步骤和代码
    ios 开发中 动态库 与静态库的区别
    Core Data使用之一(Swift): 获取
    南邮NOJ整除的尾数
    南邮NOJ卡片游戏
    南邮NOJ卡片游戏
    南邮NOJ卡片游戏
    南邮NOJ卡片游戏
  • 原文地址:https://www.cnblogs.com/zhepama/p/3028495.html
Copyright © 2020-2023  润新知