//TCP的C/S架构 //TCP客户端:net.Dial() Write() Read() Close() //TCP服务器:net.Listen() Accept() Read() Write() Close() /* Unix基本哲学之一就是“一切皆文件”, 都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。 Socket就是该模式的一个实现,网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。 Socket也具有一个类似于打开文件的函数调用:Socket(),该函数返回一个整型的Socket描述符, 随后的连接建立、数据传输等操作都是通过该Socket实现的 */ //常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。 服务端 ~~~ package main import ( "fmt" "log" "net" "strings" ) func dealConn(conn net.Conn) { defer conn.Close() ipAddr := conn.RemoteAddr().String() fmt.Println(ipAddr, "连接成功") buf := make([]byte, 1024) for { //阻塞等待用户发送的数据 n, err := conn.Read(buf) if err != nil { fmt.Println(err) return } //切片截取,只截取有效数据 result := buf[:n] fmt.Printf("接收到数据来自[%s]==>[%d]:%s\n", ipAddr, n, string(result)) if "exit" == string(result) { fmt.Println(ipAddr, "退出连接") return } conn.Write([]byte(strings.ToUpper(string(result)))) } } func main() { listenner, err := net.Listen("tcp", "127.0.0.1:8001") //go中的接口被占用报错:An attempt was made to access a socket in a way forbidden by its access permissions. if err != nil { log.Fatal(err) //log.Fatal()会产生panic } for { conn, err := listenner.Accept() if err != nil { log.Println(err) continue } go dealConn(conn) } } ~~~ 客户端 ~~~ package main import ( "fmt" "log" "net" ) func main() { //客户端主动连接服务器 conn, err := net.Dial("tcp", "127.0.0.1:8001") if err != nil { log.Fatal(err) //log.Fatal()会产生panic return } defer conn.Close() //关闭 buf := make([]byte, 1024) //缓冲区 for { fmt.Printf("请输入发送的内容:") fmt.Scan(&buf) //相当于Python中的input-->>buf = input("请输入发送的内容") fmt.Printf("发送的内容:%s\n", string(buf)) conn.Write(buf) n, err := conn.Read(buf) if err != nil { fmt.Println(err) return } result := buf[:n] fmt.Printf("接收到数据[%d]:%s\n", n, string(result)) } } ~~~