package main import ( "bytes" "fmt" "net" "time" ) func main() { listener, err := net.Listen("tcp", "127.0.0.1:9527") defer listener.Close() if err != nil { fmt.Printf("server err %v\n", err) } else { for { conn, err := listener.Accept() if err == nil { go handleConn(conn) } } } } func Read(conn net.Conn) (string, error) { readBytes := make([]byte, 1) var buf bytes.Buffer for { _, err := conn.Read(readBytes) if err != nil { return "", err } readByte := readBytes[0] if readByte == '\t' { break } } return buf.String(), nil } func Write(conn net.Conn, content string) (int, error) { var buf bytes.Buffer buf.WriteString(content) buf.WriteByte('\t') return conn.Write(buf.Bytes()) } func handleConn(conn net.Conn) { for { conn.SetReadDeadline(time.Now().Add(2)) if str, err := Read(conn); err == nil { fmt.Printf("收到的数据:%v\n", str) Write(conn, "server got:"+str) }else{ fmt.Printf("read err: %v\n",err) } } }
现在用 telnet 发送消息,然后报错 read err: read tcp 127.0.0.1:9527->127.0.0.1:56508: i/o timeout
![]() | 1 codehz 2021-04-06 22:55:28 +08:00 time 的 add 默认单位是纳秒( |
2 awanganddong OP ![]() 设置为以下还是同样报错 conn.SetReadDeadline(time.Now().Add(10 * time.Second)) |
![]() | 3 codehz 2021-04-06 23:07:42 +08:00 所以你发送的内容有没有包含制表符呢 |
4 awanganddong OP ![]() @codehz 我把制表符剔除试下 |
5 djoiwhud 2021-04-07 01:44:10 +08:00 via Android 我看了两分钟也没看出你这个 read 里面定义的 buf 是什么用途。 每次读一个字节的操作看起来是学习练手的。看得出你没认真读过计算机网络卷一。 另外 read 的 len 返回值务必处理。 |
![]() | 6 writesome6 2021-04-07 09:43:13 +08:00 其实就是你设置的超时时间有问题 |
7 1000172 2021-04-07 10:45:53 +08:00 我之前用框架写时遇到连不通是因为跨域的问题(因为我用网页测试,框架内默认进行跨域验证,我重写了跨域验证方法后就好了),你这个没太仔细看,只是送点参考意见 |
![]() | 8 bruce0 2021-04-07 10:52:24 +08:00 ``` func Read(conn net.Conn) (string, error) { readBytes := make([]byte, 1) var buf bytes.Buffer for { _, err := conn.Read(readBytes) if err != nil { return "", err } readByte := readBytes[0] if readByte == '\t' { break } } return buf.String(), nil } ``` readBytes := make([]byte, 1) 这里你创建的这个切片,长度是 1, 一般没有这样设置的. 一般都是客户端和服务端约定一个包最大长度,比如 1024, 每次客户端和服务端发的数据都不会超过这个最大长度, n, err := conn.Read(readBytes) 通过这个函数读的时候, 返回的 n 是这次读取的长度 而你现在传了一个长度为 1 的切片, 假设这次客户端发来的数据长度为 10 因为你的切片长度为 1 就只能读到第位 后面的都丢了 |
9 awanganddong OP 以上是我参照别人 demo 写的,里边逻辑确实有问题。 |
![]() | 10 skiy 2021-04-07 12:56:14 +08:00 你的 buf.String() 永远是"" |
11 crescentBLADE 2021-04-08 18:11:26 +08:00 你这是意识流 |
12 awanganddong OP 属于瞎几把写,我再重新修改修改,里边逻辑不太对 |
13 awanganddong OP socket 属于流的模式 这个要搞明白 以下是修改的代码 ``` package main import ( "fmt" "io" "net" ) func main() { listener, err := net.Listen("tcp", "127.0.0.1:9527") if err != nil { fmt.Printf("server err %v\n", err) } defer listener.Close() for { conn, err := listener.Accept() if err == nil { go handleConn(conn) } } } func handleConn(conn net.Conn) { for { readBytes := make([]byte, 1) n, err := conn.Read(readBytes) if err != nil && err != io.EOF { fmt.Printf("read err:%v\n", err) break } fmt.Printf("read content:%v", readBytes[:n]) _, err = conn.Write(readBytes[:n]) if err != nil { fmt.Printf("write err:%v\n", err) break } } } ``` |
![]() | 14 who1996 2021-05-06 17:42:10 +08:00 tcp 没有跨域,,跨域是因为 client 端的安全策略!!! |