如何解决从套接字重复读取
开始版本: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()) }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。