This is the way of TCP sockets. “Write” means to put the bytes into the kernel 
send buffer and is essentially nonblocking within that buffer size. Connection 
errors are more often detected on the next read operation, which naturally 
blocks waiting for the next network event / packet.

//jb

On 24 Dec 2018, at 15:20, "eran.ya...@gmail.com<mailto:eran.ya...@gmail.com>" 
<eran.ya...@gmail.com<mailto:eran.ya...@gmail.com>> wrote:

Hi,

I am experiencing an issue in *Conn.Write() which is not detecting that the 
connection was closed in the server.
Below you can find demo SSL server and client which hosted on same go project.
The problem is that the following line doesn't detect closed socket/connection:

conn.Write([]byte("hello\n"))

Below is the full code:


package main

import (
 "bufio"
 "crypto/tls"
 "log"
 "net"
 "time"
)

func handleConnection(conn net.Conn) {
 defer conn.Close()
 r := bufio.NewReader(conn)
 for {
   msg, err := r.ReadString('\n')
   if err != nil {
     log.Println(err)
     return
   }

   println(msg)

   n, err := conn.Write([]byte("world\n"))
   if err != nil {
     log.Println(n, err)
     return
   }
 }
}

func server() {
 log.SetFlags(log.Lshortfile)

 cer, err := tls.LoadX509KeyPair("cert.crt", "key.key")
 if err != nil {
   log.Println(err)
   return
 }

 config := &tls.Config{Certificates: []tls.Certificate{cer}}
 ln, err := tls.Listen("tcp", ":5000", config)
 if err != nil {
   log.Println(err)
   return
 }

 defer ln.Close()

 sConn, err = ln.Accept()
 if err != nil {
   log.Println(err)
 }

 handleConnection(sConn)
}

var sConn net.Conn

func client() {
 log.SetFlags(log.Lshortfile)

 conf := &tls.Config{
   InsecureSkipVerify: true,
 }

 conn, err := tls.Dial("tcp", "127.0.0.1:5000", conf)
 if err != nil {
   log.Println(err)
   return
 }

 //close the server connection to simulate Write() doesn't detect closed 
socket/connection
 sConn.Close()

 //Should return err. but instead it returns n =6 and err = nil.
 //would expect it to return n=0 and socket/connection is closed
 n, err := conn.Write([]byte("hello\n"))
 if err != nil {
   log.Println(n, err)
   return
 }

 buf := make([]byte, 100)
 n, err = conn.Read(buf)
 if err != nil {
   log.Println(n, err)
   return
 }

 println(string(buf[:n]))
}

func main() {
 go func() {
   server();
 }()

 //sleep to make sure server hits ln.Accept()
 time.Sleep(time.Second * 2)

 client()
}


The only code that detects that a connection/socket is closed it conn.Read() or 
r.ReadString()
I appreciate the help.


--
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to 
golang-nuts+unsubscr...@googlegroups.com<mailto:golang-nuts+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to