【go】golang设计一个tcp服务器端接收信息

golang">func handlerConn(conn net.Conn) {

//获取客户端信息 info,并返回 info+服务器时间

var buf [1024]byte

for {

readSize, err := conn.Read(buf[0:])

dealErrorWithReturn(err)

remoteAddr := conn.RemoteAddr()

fmt.Println("来自远程ip:", remoteAddr, " 的消息:", string(buf[0:readSize]))

_, err2 := conn.Write([]byte(string(buf[0:readSize]) + " " + time.Now().String()))

//一定要执行下面的return 才能监听到客户端主动断开,服务器端对本次conn进行close处理 dealErrorWithReturn不能达到这个效果。

if err2 != nil {

return

}

}

}

如上,buf大小必须要指定,可是实际开发中,并不知道buf多大,请问,怎么设计这个buf的大小?

一般情况下,这个大小是知道的,下面列举几种情况:

  1. web 服务器收到请求时,首部Content-Length就指定的包体的大小;
  2. 自己编写tcp服务器的时候,因为tcp是基于流的,不能区分边界。所以一般我们在消息的前面增加几个字节的长度信息,2字节或者4字节。例如要发一个Hello World!,长度为12,将12转成网络字节序,然后放在消息前发送,再发送消息。服务器收到消息时,先读取到长度12,然后分配buff,读取剩下的消息。

另外io/ioutil提供了ReadAll方法,从一个io.Reader中读取字符串,直到遇到io.EOF结束。

它的实现也很简单,就是先分配1024的长度,然后读取数据,io.Reader会返回读取数据的长度,如果未遇到io.EOF且读取的长度是1024,那么再分配2048的空间,将前1024字节拷贝过来,继续读取,直到结束或出错。

网络编程缓冲区一般设置为512的倍数,java的BufferedInputStream中缓冲区大小是8192,你可以参考

一般而言,缓冲区大小在“内存使用”与“传输效率”间取平衡值。

  1. 要减小内存使用,用小缓冲区。例如 256B。
  2. 要提高传输效率,用大缓冲区。例如 64K。

在本例中,你不需要存储完整的内容,可以边收边发。
纠结的是接收内容的长度,这个得有约定协议,否则在网络不稳定情况容易出错。
常见的协议如

  1. 以特殊字节(串)结尾。例如:以换行符 "n" 标志内容结束。
  2. 内容长度发送在前,内容在后。例如:内容长度用一个字节表示,那么 "x03ABC" 代表内容是 "ABC"。

无论采取哪种协议,你的代码要稍作修改,改成循环读取,直到内容结束,如

// 本例省略错误判断。

var buf [256]byte

for {

// 收

n, err := conn.Read(buf[:])

// 发

conn.Write(buf[:n])

// 判断内容是否结束

if endOfRequest(...) {

// 发时间戳

conn.Write(...)

break

}

}

回答

以上是 【go】golang设计一个tcp服务器端接收信息 的全部内容, 来源链接: www.h5w3.com/114887.html

回到顶部