jjzjj

sockets - conn (net.Conn) 并不总是写在套接字上

coder 2024-07-07 原文

我已经用服务器和客户端完成了一个应用程序,以使用套接字 TCP 发送信息

问题是,如果函数 zfs.ReceiveSnapshot(在服务器端)没有返回错误(err == nil),conn.Write([]byte("0"))不工作,客户端没有收到任何字节继续,它不能关闭连接...

我给你看服务器端和客户端的代码

服务器:

package main

import (
    "net"
    "github.com/mistifyio/go-zfs"
)

func main() {
    // Listen for incoming connections
    l, _ := net.Listen("tcp", ":7766")

    // Close the listener when the application closes
    defer l.Close()
    fmt.Println("Listening on port 7766...")
    for {
        // Listen for an incoming connection.
        conn, _ := l.Accept()
        // Handle connections in a new goroutine.
        go handleRequest(conn)
    }
}

// Handles incoming requests
func handleRequest(conn net.Conn) {
    // Receive snapshot
    _, err := zfs.ReceiveSnapshot(conn, "tank/replication")
    if err != nil {
        conn.Write([]byte("1"))
        zfs.ReceiveSnapshot(conn, "tank/replication")
        conn.Close()
    } else {
        conn.Write([]byte("0"))
        conn.Close()
    }
}

客户:

package main

import (
    "net"
    "github.com/mistifyio/go-zfs"
)

func main() {
    conn, _ := net.Dial("tcp", "192.168.99.5:7766")

    for i := 0; i < 1; i++ {
        // Get all snapshots in tank/test
        take, _ := zfs.Snapshots("tank/test")

        // Select snapshots
        snap := take[0].Name
        ds1, _ := zfs.GetDataset(snap)

        // Send first snapshot
        ds1.SendSnapshot(conn)
        defer conn.Close()

        buff := make([]byte, 1024)
        n, _ := conn.Read(buff)

        if n != 0 {
            snap = take[1].Name
            ds2, _ := zfs.GetDataset(snap)
            zfs.SendSnapshotIncremental(conn, ds1, ds2, zfs.IncrementalStream)
            conn.Close()
        }
    }
}

[编辑]: 如果 ReceiveSnapshots 返回错误,conn.Write([]byte) 写入“1”,客户端接收它,执行 SendSnapshotIncremental(如果 n != 0 执行)并关闭客户端的连接。 .. 但是,如果 ReceiveSnapshot 没有返回错误,conn.Write([]byte) 不会写“0”,只是我用 ctrl+C 关闭服务器端的连接

最佳答案

我认为问题在于这些行:

buff := make([]byte, 1024)
n, _ := conn.Read(buff)

在这种情况下,n 是读取的字节的数量,而不是其中任何一个的值。

我会:

buff := make([]byte, 1)
n,err := conn.Read(buff)
buff = buff[:n]
if len(buff) == 0 {
   //error
}

if(buff[0] != 0){...

关于sockets - conn (net.Conn) 并不总是写在套接字上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44137432/

有关sockets - conn (net.Conn) 并不总是写在套接字上的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  3. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  4. ruby-on-rails - Rails - 乐观锁定总是触发 StaleObjectError 异常 - 2

    我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd

  5. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  6. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  7. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

  8. .net - .NET 将如何影响 Python 和 Ruby 应用程序? - 2

    我很好奇.NET将如何影响Python和Ruby应用程序。用IronPython/IronRuby编写的应用程序是否会非常特定于.NET环境,以至于它们实际上将变得特定于平台?如果他们不使用任何.NET功能,那么IronPython/IronRuby相对于非.NET同类产品的优势是什么? 最佳答案 我不能说任何关于IronRuby的东西,但是大多数Python实现(如IronPython、Jython和PyPy)都试图尽可能忠实于CPython实现。不过,IronPython正在迅速成为这方面的佼佼者之一,并且在PlanetPyth

  9. ruby - 是否可以在不实际发送或读取数据的情况下查明 ruby​​ 套接字是否处于 ESTABLISHED 或 CLOSE_WAIT 状态? - 2

    s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成

  10. ruby-on-rails - Ruby 的 'open_uri' 是否在读取或失败后可靠地关闭套接字? - 2

    一段时间以来,我一直在使用open_uri下拉ftp路径作为数据源,但突然发现我几乎连续不断地收到“530抱歉,允许的最大客户端数(95)已经连接。”我不确定我的代码是否有问题,或者是否是其他人在访问服务器,不幸的是,我无法真正确定谁有问题。本质上,我正在读取FTPURI:defself.read_uri(uri)beginuri=open(uri).readuri=="Error"?nil:urirescueOpenURI::HTTPErrornilendend我猜我需要在这里添加一些额外的错误处理代码...我想确保我采取一切预防措施来关闭所有连接,这样我的连接就不是问题所在,但是我

随机推荐