Go语言编程基础:Tcp编程基础

131 阅读1分钟
端口

这里的端口并不是物理意义上的端口,而是特指TCP/IP协议中的端口,
是逻辑意义上的端口。

如果把IP地址比作一间房子,端口就是出入这件房子的门。
端口使用端口号来进行标记,它们都是整数,范围:0~65535

0号是保留端口号

1~1024是固定端口(程序员不可使用)
这些端口号被某些程序固定使用。
22SSH远程登陆协议  23:telnet使用  21:ftp使用
25:smtp服务使用     80:iis使用     7:echo服务

1025~65535是动态端口(程序员可使用)

示例:
//server端
package main

import (
	"fmt"
	"net"
)

func process(conn net.Conn) { //Conn是一个基本的接口类型,以数据流为向导的网络连接接口。
	defer conn.Close()
	
	for {
		buf := make([]byte, 1024)
		fmt.Printf("wait for client:%s send message\n", conn.RemoteAddr().String())//RemoteAddr()可以获取客户端的地址和端口号
		n, err := conn.Read(buf)//读取未知长度数据到buf中
		if err != nil {//读取失败
			fmt.Printf("wrong! client out = %v", err)
			return
		}
		fmt.Print(string(buf[:n]))
	}
}

func main() {
	fmt.Println("server running")
	listen, err := net.Listen("tcp", "0.0.0.0:8888")
	if err != nil {
		fmt.Println("listen err =", err)
		return
	}
	defer listen.Close()
	
	for {
		fmt.Println("wait for client connected")
		conn, err := listen.Accept()
		if err != nil {
			fmt.Println("Accept() err =", err)
		}else {
			fmt.Printf("Accept() suc con = %v  client ip = %v\n", conn, conn.RemoteAddr().String())
		}
		go process(conn)
	}
}

//client
package main

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

func main() {
    conn, err := net.Dial("tcp", "192.168.20.253:8888")

    if err != nil {
        fmt.Println("client dial err=", err)
        return

    }

    //功能一:客户端可以发送单行数据,然后就退出
    reader := bufio.NewReader(os.Stdin) //os.Stdin 代表标准输入[终端]

    //从终端读取一行用户输入,并准备发送给服务器
    line, err := reader.ReadString('\n')//以回车符结束
    if err != nil {
        fmt.Println("readString err=", err)
    
    }

    //再将 line 发送给 服务器
    n, err := conn.Write([]byte(line))
    if err != nil {
        fmt.Println("conn.Write err=", err)

    }

    fmt.Printf("客户端发送了 %d 字节的数据,并退出", n)

}