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
|  |      1codehz      2021-04-06 22:55:28 +08:00 time 的 add 默认单位是纳秒( | 
|      2awanganddong OP  1 设置为以下还是同样报错 conn.SetReadDeadline(time.Now().Add(10 * time.Second)) | 
|  |      3codehz      2021-04-06 23:07:42 +08:00 所以你发送的内容有没有包含制表符呢 | 
|      4awanganddong OP  1 @codehz 我把制表符剔除试下 | 
|      5djoiwhud      2021-04-07 01:44:10 +08:00 via Android 我看了两分钟也没看出你这个 read 里面定义的 buf 是什么用途。 每次读一个字节的操作看起来是学习练手的。看得出你没认真读过计算机网络卷一。 另外 read 的 len 返回值务必处理。 | 
|  |      6writesome6      2021-04-07 09:43:13 +08:00 其实就是你设置的超时时间有问题 | 
|      71000172      2021-04-07 10:45:53 +08:00 我之前用框架写时遇到连不通是因为跨域的问题(因为我用网页测试,框架内默认进行跨域验证,我重写了跨域验证方法后就好了),你这个没太仔细看,只是送点参考意见 | 
|  |      8bruce0      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 就只能读到第位 后面的都丢了 | 
|      9awanganddong OP 以上是我参照别人 demo 写的,里边逻辑确实有问题。 | 
|  |      10skiy      2021-04-07 12:56:14 +08:00 你的 buf.String() 永远是"" | 
|      11crescentBLADE      2021-04-08 18:11:26 +08:00 你这是意识流 | 
|      12awanganddong OP 属于瞎几把写,我再重新修改修改,里边逻辑不太对 | 
|      13awanganddong 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 } } } ``` | 
|  |      14who1996      2021-05-06 17:42:10 +08:00 tcp 没有跨域,,跨域是因为 client 端的安全策略!!! |