fix:“RawConn 不稳定导致连接被误杀

This commit is contained in:
nnbcccscdscdsc
2026-03-23 22:04:09 +08:00
parent 32e77df476
commit ce84ddb591
3 changed files with 43 additions and 2 deletions

2
.gitignore vendored
View File

@@ -1,2 +1,2 @@
bin/*
inbox/*

View File

@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"io"
"strings"
"syscall"
"time"
@@ -150,9 +151,15 @@ func (c *TCPConn) writeFrameLinux(frame []byte) error {
}
})
if err != nil {
if isRawConnNotPollable(err) {
return writeFullFallback(c.conn, frame[written:])
}
return err
}
if opErr != nil {
if isRawConnNotPollable(opErr) {
return writeFullFallback(c.conn, frame[written:])
}
return opErr
}
if written != len(frame) {
@@ -367,6 +374,15 @@ func (c *TCPConn) readFullLinux(buf []byte) (int64, error) {
firstRXTime = rxTimestamp
}
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 {
return firstRXTime, io.ErrUnexpectedEOF
}
@@ -460,3 +476,27 @@ func parseSCMTimestampingData(data []byte) int64 {
func isWouldBlock(err error) bool {
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
}

View File

@@ -97,7 +97,7 @@ func main() {
}
log.Printf("sent file %s to %s", *filePath, *targetPeer)
}
//交互式模式:如果启用了交互式模式,则启动一个 REPL 循环,允许用户在命令行输入多条发送文本或文件的命令,直到用户输入退出命令或接收循环发生错误。如果没有启用交互式模式,则等待接收循环结束,如果接收循环发生错误,则打印错误日志。
if *interactive {
if err := runInteractiveShell(client, os.Stdin, os.Stdout, receiveErr); err != nil {
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 {
printInteractiveHelp(out)
lines, inputErr := readInteractiveLines(in, out, fmt.Sprintf("%s> ", client.ID()))