问题描述
开始版本:SELECT disTINCT ON (primary_key_col_1,primary_key_col_2) * FROM edit_d
ORDER BY primary_key_col_1,primary_key_col_2,primary_key_col_3 DESC;
TCP服务器
go1.14.4 darwin/amd64
TCP客户端
package main
import (
"fmt"
"io"
"net"
"time"
)
const (
maxBufLen int = 4 * 1024
)
type Server struct {
}
func (s *Server) Start() {
listener,err := net.Listen("tcp","localhost:9001")
if err != nil {
panic(err)
}
var connections []net.Conn
defer func() {
for _,conn := range connections {
// ignore
_ = conn.Close()
}
}()
// loop...
for {
connected,err := listener.Accept()
if err != nil {
if ne,ok := err.(net.Error); ok && ne.Temporary() {
// temporary err will bi ignored
continue
} else {
fmt.Println(err)
return
}
}
go handleConn(connected,true)
connections = append(connections,connected)
}
}
func handleConn(conn net.Conn,server bool) {
buf := make([]byte,maxBufLen)
for {
// read
setTimeout(conn)
_,err := conn.Read(buf)
if err != nil {
if ne,ok := err.(net.Error); ok && (ne.Timeout() || ne.Temporary()) {
fmt.Println("need continue...")
continue
}
if err == io.EOF {
fmt.Println("EOF")
break
}
// other...
panic(err)
}
// handle recv msg.
s := string(buf)
if server {
//fmt.Println("server recv req ",s)
} else {
fmt.Println("client recv resp ",s)
}
if server {
output := "hi " + s
ob := []byte(output)
_,err := conn.Write(ob)
if err != nil {
fmt.Println(err)
break
}
}
}
}
func setTimeout(conn net.Conn) {
setErr := conn.SetReadDeadline(time.Now().Add(20 * time.Second))
if setErr != nil {
panic(setErr)
}
}
主要功能
package main
import (
"net"
"time"
)
type Client struct {
Exit chan struct{}
}
func (c *Client) Start() {
conn,err := net.Dial("tcp","localhost:9001")
if err != nil {
panic(err)
}
defer conn.Close()
go handleWrite(conn)
go handleConn(conn,false)
<-c.Exit
}
func handleWrite(conn net.Conn) {
for {
input := "carryxyh"
_,err := conn.Write([]byte(input))
if err != nil {
panic(err)
}
<-time.After(100 * time.Second)
}
}
正在运行package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
type Starter interface {
Start()
}
func main() {
var s Server
var c Client
go s.Start()
go c.Start()
sigs := make(chan os.Signal)
signal.Notify(sigs,syscall.SIGINT,syscall.SIGTERM)
<-sigs
c.Exit <- struct{}{}
fmt.Println("exit")
}
将会打印:
package main
打印两次。但是从程序角度来看,服务器仅向客户端写入一次信息,并且信息的内容应为client recv resp hi carryxyh
client recv resp carryxyh
。但是客户除了hi carryxyh
之外还打印了carryxyh
,这让我很困惑。
如上所述,我修改了服务器响应信息:hi carryxyh
=> output := "hi "+ s
,这时程序仅打印output := "hi "
。
这使我完全困惑,有人可以帮助我解决这个问题吗?如果有故障排除的主意会更好。
解决方法
这里您忽略了读取的字节长度,可能返回0个字节,你又把buf的内容又回写给客户端了。 _,err:= conn.Read(buf)改成bytesRead,err:= conn.Read(buf); if bytesRead
- 例如:
如果bytesRead == 0 && err == nil { 误差= io.EOF log.Errorf(“ [network] ReadOnce可能总是返回(0,nil)并导致死循环,连接=%d,本地地址=%+ v,远程地址=%+ v”, c.id,c.rawConnection.LocalAddr(),c.RemoteAddr()) }