返回顶部
首页 > 资讯 > 精选 >关闭客户端连接后如何从 tcp 套接字完全读取缓冲内容?
  • 751
分享到

关闭客户端连接后如何从 tcp 套接字完全读取缓冲内容?

网络编程 2024-02-11 16:02:44 751人浏览 安东尼
摘要

PHP小编小新在网络编程中,关闭客户端连接后,如何从tcp套接字完全读取缓冲内容是一个常见问题。当客户端关闭连接时,服务器端可能仍然存在未读取的数据。为了确保完整读取缓冲内容,可以采用

PHP小编小新在网络编程中,关闭客户端连接后,如何从tcp套接字完全读取缓冲内容是一个常见问题。当客户端关闭连接时,服务器端可能仍然存在未读取的数据。为了确保完整读取缓冲内容,可以采用以下几种方法:1.使用循环读取,直到读取到数据结束标志;2.设置超时时间,如果在规定时间内未读取到数据则跳出循环;3.使用非阻塞套接字,通过轮询检查是否有数据可读。以上方法可以保证从tcp套接字中完全读取缓冲内容,提升网络通信的稳定性和可靠性。

问题内容

我有一个 Go 服务器正在侦听 tcp 套接字,在关闭期间我希望它告诉客户端停止发送更多数据,但也读取客户端迄今为止发送的所有内容。我看到的是,一旦客户端连接关闭,服务器就会停止读取,但它永远不会收到客户端认为它发送的所有内容。我认为发生的情况是操作系统正在缓冲收到的 tcp 数据包,然后在服务器关闭客户端连接时丢弃它们。

这是一个显示该问题的程序。服务器监听,然后打印出它收到的内容;客户端发送并打印出发送的内容。服务器中断客户端以停止它,但最后我希望这两个列表相同。

  • 此示例使用 bufio.scanner 读取套接字,但我也尝试过仅从连接读取字节,但得到相同的结果。

  • conn.(*net.tcpconn).closewrite() 听起来正是我想要的,但这似乎根本没有中断客户端。

  • conn.(*net.tcpconn).setreadbuffer(0) - 也尝试过此操作,但 0 不是允许的值(恐慌)。

package main

import (
    "bufio"
    "fmt"
    "net"
    "strconv"
    "sync"
    "time"
)

const port = ":8888"

var wg sync.waitgroup

func main() {
    wg.add(1)
    go func() {
        // wait for the server to start
        time.sleep(1000 * time.millisecond)
        client()
    }()

    // server listens
    wg.add(1)
    server()

    wg.wait()
}

func server() {
    defer wg.done()

    listener, err := net.listen("tcp", port)
    if err != nil {
        panic(err)
    }

    received := make([]string, 0)
    conn, err := listener.accept()
    if err != nil {
        panic(err)
    }

    defer conn.close()

    scanner := bufio.newscanner(conn)

    for i := 0; scanner.scan(); i++ {
        received = append(received, scanner.text())

        // arbitrary condition: simulate a server shutdown - interrupt the client
        if len(received) == 2 {
            _ = conn.(*net.tcpconn).close()
        }
    }

    fmt.println("server received: ", received)
}

func client() {
    defer wg.done()

    conn, err := net.dial("tcp", port)
    if err != nil {
        panic(err)
    }

    sent := make([]string, 0)
    defer conn.close()

    for i := 0; i < 50000; i++ {
        v := strconv.itoa(i)
        _, err := conn.write([]byte(v + "\n"))
        if err != nil {
            fmt.println("client interrupted:", err)
            break
        } else {
            sent = append(sent, v)
            // slow down the sends to make output readable
            //time.sleep(1 * time.millisecond)
        }
    }
    fmt.println("client sent: ", sent)
}

在我的机器上输出是这样的:

Server received:  [0 1 2]
Client interrupted: write tcp 127.0.0.1:49274->127.0.0.1:8888: write: broken pipe
Client sent:  [0 1 2 3 4 5 6 7 8 9 10 11 12 13]

解决方法

TCP仅提供可靠的双向字节流,没有任何固有语义。如果服务器希望客户端发出信号表明它不应再发送任何数据,则必须将此功能实现为应用程序协议的一部分,即 TCP 提供的纯数据传输之上的一层。

以上就是关闭客户端连接后如何从 tcp 套接字完全读取缓冲内容?的详细内容,更多请关注编程网其它相关文章!

--结束END--

本文标题: 关闭客户端连接后如何从 tcp 套接字完全读取缓冲内容?

本文链接: https://lsjlt.com/news/563520.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作