Goのネットワーキング側に飛び込んでいます。私はTCP ClientとServer 。Golang TCPクライアントはサーバーからデータを受信せず、conn.Read()でハング/ブロックします
クライアントにサーバーに接続し、簡単なメッセージ(「こんにちは」)を正常に送信できるようになりました。しかし、私は、サーバーに応答を返すようにすることはできません(または、クライアントに応答を読み込ませる)ことはできません。
ここにコードがあります。私はそれがサーバーに問題はありません伝えることができるものから、
サーバー
Address := "localhost:9999"
Addr, err := net.ResolveTCPAddr("tcp", Address)
if err != nil {
log.Fatal(err)
}
listener, err := net.ListenTCP("tcp", Addr)
if err != nil {
log.Fatal(err)
}
defer listener.Close()
//server loop
for {
conn, err := listener.Accept()
if err != nil {
continue
}
go handle(conn)
}
func handle(c net.Conn) {
totalBytes, message := connRead(c)
fmt.Println(c.RemoteAddr())
fmt.Println(string(message[:totalBytes]))
c.Write([]byte("Hi"))
fmt.Println("Replied")
c.Close()
}
func connRead(c net.Conn) (int, []byte) {
buffer := make([]byte, 4096)
totalBytes := 0
for {
n, err := c.Read(buffer)
totalBytes += n
if err != nil {
if err != io.EOF {
log.Printf("Read error: %s", err)
}
break
}
}
return totalBytes, buffer
}
クライアント
tcpAddr, err := net.ResolveTCPAddr("tcp", "localhost:9999")
if err != nil {
log.Fatal(err)
}
conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
_, err = conn.Write([]byte("Hello"))
if err != nil {
log.Fatal(err)
}
tBytes, resp := connRead(conn)
fmt.Println(tBytes)
fmt.Println(string(resp[:tBytes]))
func connRead(c net.Conn) (int, []byte) {
buffer := make([]byte, 4096)
totalBytes := 0
for {
fmt.Println("Stuck?")
n, err := c.Read(buffer)
fmt.Println("Stuck.")
totalBytes += n
fmt.Println(totalBytes)
if err != nil {
if err != io.EOF {
log.Printf("Read error: %s", err)
}
break
}
}
return totalBytes, buffer
}
。クライアントを実行すると、すべてがfmt.Println("Stuck?")
の直後に停止します。これはどういうわけか、n, err := c.Read(buffer)
のステートメントで台無しになっていることを信じています。クライアントがCtrl-Cを押しても、サーバはmesseageの長さ(5)とメッセージ( "Hello")を出力しません。私がクライアントの読み書きをコメントアウトすると、物事はスムーズに実行されます。
私は回答のためにグーグルを試みましたが、何も出てこなかった。
私は間違っていますか?クライアントでconn.Read()を間違って使用していますか?
EDIT:
私は実際のLinuxへのアクセス権を持っているので、ここSIGQUITは適切な機能のためのダンプです。
サーバー
クライアント
から、それらの多くのバイトを読み取るためにバイト数を読みますクライアントとサーバーのブロックがEOFに接続されているように見えます。実行中のアプリケーションにSIQUITを送信して、ブロックされた場所を確認します。 –
私はSIGQUITをサポートしていないWin 7を利用しています。 – JimDoe
両方のプログラムは読み取り時にブロックされます。ピアの片方または両方は、他のピアのブロックを解除するために、接続の[書き込み側を閉じる](https://godoc.org/net#TCPConn.CloseWrite)すべきです。あるいは、メッセージのフレーミングを追加して、完全なメッセージを読んだ後に読み上げを停止することもできます。 –