草庐IT

Golang Bufio 编写器不写入 TCP 连接

coder 2023-07-01 原文

我正在开发一个用 Golang 编写的小型服务器。我正在查看以下示例:

https://gist.github.com/kenshinx/5796276

当尝试从 Bufio 包中实现 Reader 和 Writer 时,只能从连接中读取。看起来它没有写任何东西(好吧,我没有收到客户端的任何东西),而且它也没有给出错误。但是,使用实际连接而不是 bufio.Writer 进行写入工作正常。

这是代码。

package main

import (
    "fmt"
    "net"
    "os"
    "bufio"
    "strings"
)

const (
    CONN_HOST = "localhost"
    CONN_TYPE = "tcp"
    CONN_PORT = "3333"
)

type Client struct{
    name string
    reader *bufio.Reader
    writer *bufio.Writer
    connection net.Conn
}

type Clients [] Client

var lobby Clients

func main() {
    c, err := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT)

    if err != nil {
        fmt.Println("Error listening:", err.Error())
        os.Exit(1)
    }

    defer c.Close()
    fmt.Println("Server listening on port " + CONN_PORT)

    go matchmaking()

    for {
        conn, err := c.Accept()
        if err != nil {
            fmt.Println("Error accepting: ", err.Error())
            os.Exit(1)
        }

        if conn != nil {
            go handleRequest(conn)
        }
    }
}

func handleRequest(conn net.Conn) {
    client := &Client{
        reader: bufio.NewReader(conn),
        writer: bufio.NewWriter(conn),
        connection:conn,
    }

    client.name, _ = client.reader.ReadString('\n') // Works fine
    client.name = strings.TrimSpace(client.name)

    lobby = append(lobby, *client)
    fmt.Println("Client connected: " + client.name)
}

func matchmaking(){
    fmt.Println("Matchmaker started!")
    for {
        for i := range lobby {
            if len(lobby) >= 2 {
                go startMatch(lobby[i], lobby[i+1] )
                lobby = append(lobby[:i], lobby[i+1:]...) // Remove from lobby
                lobby = append(lobby[:i], lobby[i+1:]...)
            }
        }
    }
}

func startMatch(client1 Client, client2 Client){
    client1.writer.WriteString("found\n") // Doens't work?
    client2.writer.WriteString("found\n") // Doens't work?

    //client1.writer.Write([]byte("found\n")) => Doensn't work either
    //client1.connection.Write([]byte("found\n")) => this works fine..?

    fmt.Println("Starting match with: " + client1.name + " and " + client2.name)
    fmt.Println("Current lobby size is: ", len(lobby))
}

正如标题所说,为什么 bufio.Writer 不写入已连接的客户端?

最佳答案

缓冲的写入器已经缓冲了数据。要进一步插入它,请调用 writer.Flush .

func startMatch(client1 Client, client2 Client){
    _, err := client1.writer.WriteString("found\n")
    // handle error here
    err = client1.writer.Flush()
    // handle error here
    _, err = client2.writer.WriteString("found\n")
    // handle error here
    err = client2.writer.Flush()
    // handle error here

    fmt.Println("Starting match with: " + client1.name + " and " + client2.name)
    fmt.Println("Current lobby size is: ", len(lobby))
}

处理刷新操作中的错误也变得很重要,因为此时潜在的编写器错误可能会冒出来。

关于Golang Bufio 编写器不写入 TCP 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49348463/

有关Golang Bufio 编写器不写入 TCP 连接的更多相关文章

  1. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  2. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  3. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  4. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  5. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  6. ruby - Ruby 是否使用 $stdout 来写入 puts 和 return 的输出? - 2

    我想知道Ruby用来在命令行打印这些东西的输出流:irb(main):001:0>a="test"=>"test"irb(main):002:0>putsatest=>nilirb(main):003:0>a=>"test"$stdout是否用于irb(main):002:0>和irb(main):003:0>?而且,在这两次调用之间,$stdout的值是否有任何变化?另外,有人能告诉我打印/写入这些内容的Ruby源代码吗? 最佳答案 是的。而且很容易向自己测试/证明。在命令行试试这个:ruby-e'puts"foo"'>test.

  7. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  8. ruby-on-rails - 如何为空白字段编写 rspec? [Rails3.1] - 2

    我使用rails3.1+rspec和factorygirl。我对必填字段(validates_presence_of)的验证工作正常。我如何让测试将该事实用作“成功”而不是“失败”规范是:describe"Addanindustrywithnoname"docontext"Unabletocreatearecordwhenthenameisblank"dosubjectdoind=Factory.create(:industry_name_blank)endit{shouldbe_invalid}endend但是我失败了:Failures:1)Addanindustrywithnona

  9. ruby-on-rails - 连接字符串时如何在 <%=%> block 内输出 html_safe? - 2

    考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://

  10. Ruby:写入 stdin 并从 stdout 读取? - 2

    我正在编写一个ruby​​程序,它应该执行另一个程序,通过stdin向它传递值,从它的stdout读取响应,然后打印响应。这是我目前所拥有的。#!/usr/bin/envrubyrequire'open3'stdin,stdout,stderr=Open3.popen3('./MyProgram')stdin.puts"helloworld!"output=stdout.readerrors=stderr.readstdin.closestdout.closestderr.closeputs"Output:"puts"-------"putsoutputputs"\nErrors:"p

随机推荐