在socket关闭或写入换行符之前,TCPConn Write不执行任何操作

时间:2015-12-03 20:26:54

标签: go tcp

在没有任何换行符或空字节分隔符的情况下调用TCPConn.Write似乎没有做任何事情,直到套接字或编写器关闭。

在这个例子中,我希望conn.Write在写入完成后立即触发服务器上的读取,但在套接字关闭之前没有任何反应。如果我在编写带有换行符的字符串之前没有它就可以正常工作。这是预期的行为吗?是否需要分隔符?或者我在这里错过了什么..

服务器

package main

import (
    "log"
    "net"
)

func main() {
    addr, _ := net.ResolveTCPAddr("tcp4", ":8080")
    l, err := net.ListenTCP("tcp4", addr)
    if err != nil {
        log.Fatal(err.Error())
    }

    defer l.Close()

    for {
        var conn *net.TCPConn
        if conn, err = l.AcceptTCP(); err != nil {
            log.Println(err.Error())
            continue
        }

        log.Println("client connected")
        go handleConnection(conn)
    }
}

func handleConnection(conn *net.TCPConn) {
    defer conn.Close()

    for {
        var b = make([]byte, 128)
        bytesRead, err := conn.Read(b)
        if err != nil {
            break
        }

        log.Printf("got: %s\n", string(b[:bytesRead]))
    }

    log.Println("client disconnected")
}

客户端

package main

import (
    "log"
    "net"
    "time"
)

func main() {
    addr, _ := net.ResolveTCPAddr("tcp", "localhost:8080")
    conn, err := net.DialTCP("tcp", nil, addr)
    if err != nil {
        log.Fatal(err.Error())
    }

    // uncommenting the following line will make the following writes work as expected
    //conn.Write([]byte("hello world\n"))

    for i := 0; i < 5; i++ {
        conn.Write([]byte("hello"))
        log.Println("wrote hello")
        time.Sleep(time.Second)
    }

    time.Sleep(time.Second)
    conn.Close()
}

2 个答案:

答案 0 :(得分:0)

逐字运行代码(客户端编写hello world仍然注释)显示:

服务器:

2015/12/04 09:57:00 client connected
2015/12/04 09:57:00 got: hello
2015/12/04 09:57:01 got: hello
2015/12/04 09:57:02 got: hello
2015/12/04 09:57:03 got: hello
2015/12/04 09:57:04 got: hello
2015/12/04 09:57:06 client disconnected

客户端:

2015/12/04 09:57:00 wrote hello
2015/12/04 09:57:01 wrote hello
2015/12/04 09:57:02 wrote hello
2015/12/04 09:57:03 wrote hello
2015/12/04 09:57:04 wrote hello

它似乎按预期工作,服务器每秒输出一次,就像客户端写的那样。

这是在以下测试: go version devel + 54bd5a7 Sat Nov 21 10:19:16 2015 +0000 linux / amd64

你在运行什么版本?

答案 1 :(得分:0)

感谢您试一试,我在Ubuntu vm上运行它,它按预期工作。因此,从Windows 1.5.1开始,它似乎是一个错误。

修改

原来它是Eset Smart Security的协议过滤,走的不是罪魁祸首