fix:“RawConn 不稳定导致连接被误杀
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,2 @@
|
|||||||
bin/*
|
bin/*
|
||||||
|
inbox/*
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -150,9 +151,15 @@ func (c *TCPConn) writeFrameLinux(frame []byte) error {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if isRawConnNotPollable(err) {
|
||||||
|
return writeFullFallback(c.conn, frame[written:])
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if opErr != nil {
|
if opErr != nil {
|
||||||
|
if isRawConnNotPollable(opErr) {
|
||||||
|
return writeFullFallback(c.conn, frame[written:])
|
||||||
|
}
|
||||||
return opErr
|
return opErr
|
||||||
}
|
}
|
||||||
if written != len(frame) {
|
if written != len(frame) {
|
||||||
@@ -367,6 +374,15 @@ func (c *TCPConn) readFullLinux(buf []byte) (int64, error) {
|
|||||||
firstRXTime = rxTimestamp
|
firstRXTime = rxTimestamp
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if isRawConnNotPollable(err) {
|
||||||
|
if fallbackErr := readFullFallback(c.conn, buf[offset:]); fallbackErr != nil {
|
||||||
|
if errors.Is(fallbackErr, io.EOF) && offset > 0 {
|
||||||
|
return firstRXTime, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
return firstRXTime, fallbackErr
|
||||||
|
}
|
||||||
|
return firstRXTime, nil
|
||||||
|
}
|
||||||
if errors.Is(err, io.EOF) && offset > 0 {
|
if errors.Is(err, io.EOF) && offset > 0 {
|
||||||
return firstRXTime, io.ErrUnexpectedEOF
|
return firstRXTime, io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
@@ -460,3 +476,27 @@ func parseSCMTimestampingData(data []byte) int64 {
|
|||||||
func isWouldBlock(err error) bool {
|
func isWouldBlock(err error) bool {
|
||||||
return errors.Is(err, syscall.EAGAIN) || errors.Is(err, syscall.EWOULDBLOCK)
|
return errors.Is(err, syscall.EAGAIN) || errors.Is(err, syscall.EWOULDBLOCK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isRawConnNotPollable(err error) bool {
|
||||||
|
return err != nil && strings.Contains(err.Error(), "not pollable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeFullFallback(w io.Writer, buf []byte) error {
|
||||||
|
for len(buf) > 0 {
|
||||||
|
n, err := w.Write(buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if n <= 0 {
|
||||||
|
return io.ErrShortWrite
|
||||||
|
}
|
||||||
|
buf = buf[n:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readFullFallback(r io.Reader, buf []byte) error {
|
||||||
|
_, err := io.ReadFull(r, buf)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
log.Printf("sent file %s to %s", *filePath, *targetPeer)
|
log.Printf("sent file %s to %s", *filePath, *targetPeer)
|
||||||
}
|
}
|
||||||
|
//交互式模式:如果启用了交互式模式,则启动一个 REPL 循环,允许用户在命令行输入多条发送文本或文件的命令,直到用户输入退出命令或接收循环发生错误。如果没有启用交互式模式,则等待接收循环结束,如果接收循环发生错误,则打印错误日志。
|
||||||
if *interactive {
|
if *interactive {
|
||||||
if err := runInteractiveShell(client, os.Stdin, os.Stdout, receiveErr); err != nil {
|
if err := runInteractiveShell(client, os.Stdin, os.Stdout, receiveErr); err != nil {
|
||||||
log.Printf("interactive shell ended: %v", err)
|
log.Printf("interactive shell ended: %v", err)
|
||||||
@@ -110,6 +110,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 在终端面板中打印报错和交互消息
|
||||||
func runInteractiveShell(client *peerpkg.Client, in io.Reader, out io.Writer, receiveErr <-chan error) error {
|
func runInteractiveShell(client *peerpkg.Client, in io.Reader, out io.Writer, receiveErr <-chan error) error {
|
||||||
printInteractiveHelp(out)
|
printInteractiveHelp(out)
|
||||||
lines, inputErr := readInteractiveLines(in, out, fmt.Sprintf("%s> ", client.ID()))
|
lines, inputErr := readInteractiveLines(in, out, fmt.Sprintf("%s> ", client.ID()))
|
||||||
|
|||||||
Reference in New Issue
Block a user