TCPAddr
type TCPAddr struct {
IP IP
Port int
}
ResolveTCPAddr函数用于创建TCPAddr
1
| func ResolveTCPAddr(net, addr string) (*TCPAddr, os.Error)
|
其中参数net是“tcp”,“tcp4”或“tcp6”之一,addr是由主机名或IP地址组成的字符串,后跟“:”后面的端口号,例如“www.google.com:80“或”127.0.0.1:22“。
1 2 3 4 5 6 7 8
| func DialTCP(net string, laddr, raddr *TCPAddr) (c *TCPConn, err os.Error)
func (c *TCPConn) SetTimeout(nsec int64) os.Error 即使客户端无需发送任何内容,客户端也可能希望保持与服务器的连接。它可以使用: func (c *TCPConn) SetKeepAlive(keepalive bool) os.Error
func (c *TCPConn) Write(b []byte) (n int, err os.Error) func (c *TCPConn) Read(b []byte) (n int, err os.Error)
|
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
package main
import ( "net" "os" "fmt" "io/ioutil" )
func main() { if len(os.Args) != 2 { fmt.Fprintf(os.Stderr, "Usage: %s host:port ", os.Args[0]) os.Exit(1) } service := os.Args[1]
tcpAddr, err := net.ResolveTCPAddr("tcp4", service) checkError(err)
conn, err := net.DialTCP("tcp", nil, tcpAddr) checkError(err)
_, err = conn.Write([]byte("HEAD / HTTP/1.0\r\n\r\n")) 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) } }
|
测试
1 2 3 4 5 6 7
| $ ./net www.baidu.com:80 HTTP/1.0 302 Found Content-Length: 17931 Content-Type: text/html Date: Fri, 18 Jan 2019 15:33:50 GMT Etag: "54d9748e-460b" Server: bfe/1.0.8.18
|
服务器
1 2
| func ListenTCP(net string, laddr *TCPAddr) (l *TCPListener, err os.Error) func (l *TCPListener) Accept() (c Conn, err os.Error)
|
ListenTCP为服务器监听端口,Accept代表锁住,等待客户端连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
package main
import ( "fmt" "net" "os" "time" )
func main() {
service := ":1200" tcpAddr, err := net.ResolveTCPAddr("tcp4", service) 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) } }
|
多线程服务器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
package main
import ( "net" "os" "fmt" )
func main() {
service := ":1201" tcpAddr, err := net.ResolveTCPAddr("tcp4", service) checkError(err)
listener, err := net.ListenTCP("tcp", tcpAddr) checkError(err)
for { conn, err := listener.Accept() if err != nil { continue } go handleClient(conn) } }
func handleClient(conn net.Conn) { defer conn.Close()
var buf [512]byte for { n, err := conn.Read(buf[0:]) if err != nil { return }
_, err2 := conn.Write(buf[0:n]) if err2 != nil { return } } }
func checkError(err error) { if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) os.Exit(1) } }
|
灾难总是接踵而至,这正是世间的常理。你以为只要哭诉一下,就会有谁来救你?如果失败了,就只能说明我不过是如此程度的男人