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了.保持連接..發送.接受.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM