我正在使用Golang编写的小型服务器上工作。我正在查看以下示例:
https://gist.github.com/kenshinx/5796276
尝试从Bufio包中实现Reader and 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没有写入连接的客户端?
答案 0 :(得分:1)
缓冲的写入器已缓冲数据。要进一步调用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))
}
在刷新操作中处理错误变得很重要,因为此时底层编写器错误可能会冒出来。