FAQ
I'm trying to recover a disconnected situation on client side. But I can
not handle it well.

1. I can not check connection property to make sure should I Close()

if ! c.Closed() { // There is no Closed() function
   c.Close()
}

2. Is there faster method (eg. just call c.Write() to write block of struct
memory?)


// client code. If write failed, it will redial after 5 second
package main

import (
"encoding/binary"
"log"
"net"
"time"
)

const someTime = 5 * time.Second

type IP4Addr struct {
IP [4]byte
Port uint16
}
type Command struct {
IP4Addr
CliConnSeq, SrvConnSeq uint32
Id uint32 // srvId*100 + proxyId*10 + cliId
Seq uint32 // srvSeq*10000 + cliSeq
}

func main() {
var dummy Command
L_DIAL:
for {
log.Println("Dialing")
c, err := net.Dial("tcp", ":20000")
if err != nil {
log.Println(err)
time.Sleep(someTime)
continue
}
for {
err = binary.Write(c, binary.LittleEndian, dummy)
if err != nil {
log.Println(err)
time.Sleep(someTime)
continue L_DIAL
}
err = binary.Read(c, binary.LittleEndian, &dummy)
if err != nil {
log.Println(err)
time.Sleep(someTime)
continue L_DIAL
}
time.Sleep(time.Second)
}
}
}

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Dave Cheney at May 28, 2013 at 1:30 am
    This has been discussed several times on the mailing list, I suggest
    you search the archives. The summary is, you cannot tell if someone
    has closed the connection without doing a Read or Write call and
    responding to the error status.
    On Tue, May 28, 2013 at 11:28 AM, dlin wrote:
    I'm trying to recover a disconnected situation on client side. But I can
    not handle it well.

    1. I can not check connection property to make sure should I Close()

    if ! c.Closed() { // There is no Closed() function
    c.Close()
    }

    2. Is there faster method (eg. just call c.Write() to write block of struct
    memory?)


    // client code. If write failed, it will redial after 5 second
    package main

    import (
    "encoding/binary"
    "log"
    "net"
    "time"
    )

    const someTime = 5 * time.Second

    type IP4Addr struct {
    IP [4]byte
    Port uint16
    }
    type Command struct {
    IP4Addr
    CliConnSeq, SrvConnSeq uint32
    Id uint32 // srvId*100 + proxyId*10 + cliId
    Seq uint32 // srvSeq*10000 + cliSeq
    }

    func main() {
    var dummy Command
    L_DIAL:
    for {
    log.Println("Dialing")
    c, err := net.Dial("tcp", ":20000")
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue
    }
    for {
    err = binary.Write(c, binary.LittleEndian, dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    err = binary.Read(c, binary.LittleEndian, &dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    time.Sleep(time.Second)
    }
    }
    }

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dlin at May 28, 2013 at 1:45 am
    So, maybe one solution is writing a wrapper by myself?

    type MyConn struct {
       net.Conn
       opened bool
    }
    func (c *MyConn )Dial(...) {
       c.Conn.Dial(...)
        opened = true // if not err
    }
    func (c *MyConn )Close(...) {
       c.Conn.Close(...)
       opened = false
    }
    func (c *MyConn )Write(...) {
       c.Conn.Write(...)
       if err {
         c.Close()
       }
    }
    func (c *MyConn )Read(...) {
       c.Conn.Read(...)
       if err {
         c.Close()
       }
    }
    On Tuesday, May 28, 2013 9:30:46 AM UTC+8, Dave Cheney wrote:

    This has been discussed several times on the mailing list, I suggest
    you search the archives. The summary is, you cannot tell if someone
    has closed the connection without doing a Read or Write call and
    responding to the error status.

    On Tue, May 28, 2013 at 11:28 AM, dlin <dli...@gmail.com <javascript:>>
    wrote:
    I'm trying to recover a disconnected situation on client side. But I can
    not handle it well.

    1. I can not check connection property to make sure should I Close()

    if ! c.Closed() { // There is no Closed() function
    c.Close()
    }

    2. Is there faster method (eg. just call c.Write() to write block of struct
    memory?)


    // client code. If write failed, it will redial after 5 second
    package main

    import (
    "encoding/binary"
    "log"
    "net"
    "time"
    )

    const someTime = 5 * time.Second

    type IP4Addr struct {
    IP [4]byte
    Port uint16
    }
    type Command struct {
    IP4Addr
    CliConnSeq, SrvConnSeq uint32
    Id uint32 // srvId*100 + proxyId*10 + cliId
    Seq uint32 // srvSeq*10000 + cliSeq
    }

    func main() {
    var dummy Command
    L_DIAL:
    for {
    log.Println("Dialing")
    c, err := net.Dial("tcp", ":20000")
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue
    }
    for {
    err = binary.Write(c, binary.LittleEndian, dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    err = binary.Read(c, binary.LittleEndian, &dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    time.Sleep(time.Second)
    }
    }
    }

    --
    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...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dave Cheney at May 28, 2013 at 1:46 am
    Can you please describe the problem you are solving, not the solution
    you have come up with.
    On Tue, May 28, 2013 at 11:45 AM, dlin wrote:
    So, maybe one solution is writing a wrapper by myself?

    type MyConn struct {
    net.Conn
    opened bool
    }
    func (c *MyConn )Dial(...) {
    c.Conn.Dial(...)
    opened = true // if not err
    }
    func (c *MyConn )Close(...) {
    c.Conn.Close(...)
    opened = false
    }
    func (c *MyConn )Write(...) {
    c.Conn.Write(...)
    if err {
    c.Close()
    }
    }
    func (c *MyConn )Read(...) {
    c.Conn.Read(...)
    if err {
    c.Close()
    }
    }
    On Tuesday, May 28, 2013 9:30:46 AM UTC+8, Dave Cheney wrote:

    This has been discussed several times on the mailing list, I suggest
    you search the archives. The summary is, you cannot tell if someone
    has closed the connection without doing a Read or Write call and
    responding to the error status.
    On Tue, May 28, 2013 at 11:28 AM, dlin wrote:
    I'm trying to recover a disconnected situation on client side. But I
    can
    not handle it well.

    1. I can not check connection property to make sure should I Close()

    if ! c.Closed() { // There is no Closed() function
    c.Close()
    }

    2. Is there faster method (eg. just call c.Write() to write block of
    struct
    memory?)


    // client code. If write failed, it will redial after 5 second
    package main

    import (
    "encoding/binary"
    "log"
    "net"
    "time"
    )

    const someTime = 5 * time.Second

    type IP4Addr struct {
    IP [4]byte
    Port uint16
    }
    type Command struct {
    IP4Addr
    CliConnSeq, SrvConnSeq uint32
    Id uint32 // srvId*100 + proxyId*10 + cliId
    Seq uint32 // srvSeq*10000 + cliSeq
    }

    func main() {
    var dummy Command
    L_DIAL:
    for {
    log.Println("Dialing")
    c, err := net.Dial("tcp", ":20000")
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue
    }
    for {
    err = binary.Write(c, binary.LittleEndian, dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    err = binary.Read(c, binary.LittleEndian, &dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    time.Sleep(time.Second)
    }
    }
    }

    --
    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...@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dlin at May 28, 2013 at 2:04 am
    I'm sorry I can not explain the question well. So, I try to use code to
    explain.

    My problem is: I'm trying to implement a async protocol, one goroutine for
    Read, one goroutine for Write.
    When client try to Write()/Read() but fail, I'll return back to the main
    goroutine.
    If I don't know the status of Connection maybe one of the goroutine may
    hang forever.
    for example, sendCmdsToSrv call Write() and failed, it quit. But recvCmdsFromSrv()
    may still waiting response. So the WaitGroup still waiting.

    func srvService(srvAddr string) chan<- Command {
    c := make(chan Command, *maxCommands)
    go func(c chan Command) {
    for srvConnSeq := uint32(0); ; srvConnSeq++ {
    err := dialServer(srvConnSeq, &srvConn, srvAddr)
    if err != nil {
    break
    }
    var wg sync.WaitGroup
    wg.Add(2)
    go func() {
    sendCmdsToSrv(srvConn, srvConnSeq, c)
    wg.Done()
    }()
    go func() {
    recvCmdsFromSrv(srvConn, srvConnSeq, c)
    wg.Done()
    }()
    wg.Wait()
    }
    }(c)
    return c
    }

    On Tuesday, May 28, 2013 9:46:36 AM UTC+8, Dave Cheney wrote:

    Can you please describe the problem you are solving, not the solution
    you have come up with.

    On Tue, May 28, 2013 at 11:45 AM, dlin <dli...@gmail.com <javascript:>>
    wrote:
    So, maybe one solution is writing a wrapper by myself?

    type MyConn struct {
    net.Conn
    opened bool
    }
    func (c *MyConn )Dial(...) {
    c.Conn.Dial(...)
    opened = true // if not err
    }
    func (c *MyConn )Close(...) {
    c.Conn.Close(...)
    opened = false
    }
    func (c *MyConn )Write(...) {
    c.Conn.Write(...)
    if err {
    c.Close()
    }
    }
    func (c *MyConn )Read(...) {
    c.Conn.Read(...)
    if err {
    c.Close()
    }
    }
    On Tuesday, May 28, 2013 9:30:46 AM UTC+8, Dave Cheney wrote:

    This has been discussed several times on the mailing list, I suggest
    you search the archives. The summary is, you cannot tell if someone
    has closed the connection without doing a Read or Write call and
    responding to the error status.
    On Tue, May 28, 2013 at 11:28 AM, dlin wrote:
    I'm trying to recover a disconnected situation on client side. But I
    can
    not handle it well.

    1. I can not check connection property to make sure should I Close()

    if ! c.Closed() { // There is no Closed() function
    c.Close()
    }

    2. Is there faster method (eg. just call c.Write() to write block of
    struct
    memory?)


    // client code. If write failed, it will redial after 5 second
    package main

    import (
    "encoding/binary"
    "log"
    "net"
    "time"
    )

    const someTime = 5 * time.Second

    type IP4Addr struct {
    IP [4]byte
    Port uint16
    }
    type Command struct {
    IP4Addr
    CliConnSeq, SrvConnSeq uint32
    Id uint32 // srvId*100 + proxyId*10 + cliId
    Seq uint32 // srvSeq*10000 + cliSeq
    }

    func main() {
    var dummy Command
    L_DIAL:
    for {
    log.Println("Dialing")
    c, err := net.Dial("tcp", ":20000")
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue
    }
    for {
    err = binary.Write(c, binary.LittleEndian, dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    err = binary.Read(c, binary.LittleEndian, &dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    time.Sleep(time.Second)
    }
    }
    }

    --
    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...@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dave Cheney at May 28, 2013 at 2:32 am
    If you close the socket all reads and writes waiting will return io.EOF.
    On 28/05/2013, at 12:04, dlin wrote:

    I'm sorry I can not explain the question well. So, I try to use code to explain.

    My problem is: I'm trying to implement a async protocol, one goroutine for Read, one goroutine for Write.
    When client try to Write()/Read() but fail, I'll return back to the main goroutine.
    If I don't know the status of Connection maybe one of the goroutine may hang forever.
    for example, sendCmdsToSrv call Write() and failed, it quit. But recvCmdsFromSrv() may still waiting response. So the WaitGroup still waiting.

    func srvService(srvAddr string) chan<- Command {
    c := make(chan Command, *maxCommands)
    go func(c chan Command) {
    for srvConnSeq := uint32(0); ; srvConnSeq++ {
    err := dialServer(srvConnSeq, &srvConn, srvAddr)
    if err != nil {
    break
    }
    var wg sync.WaitGroup
    wg.Add(2)
    go func() {
    sendCmdsToSrv(srvConn, srvConnSeq, c)
    wg.Done()
    }()
    go func() {
    recvCmdsFromSrv(srvConn, srvConnSeq, c)
    wg.Done()
    }()
    wg.Wait()
    }
    }(c)
    return c
    }

    On Tuesday, May 28, 2013 9:46:36 AM UTC+8, Dave Cheney wrote:

    Can you please describe the problem you are solving, not the solution
    you have come up with.
    On Tue, May 28, 2013 at 11:45 AM, dlin wrote:
    So, maybe one solution is writing a wrapper by myself?

    type MyConn struct {
    net.Conn
    opened bool
    }
    func (c *MyConn )Dial(...) {
    c.Conn.Dial(...)
    opened = true // if not err
    }
    func (c *MyConn )Close(...) {
    c.Conn.Close(...)
    opened = false
    }
    func (c *MyConn )Write(...) {
    c.Conn.Write(...)
    if err {
    c.Close()
    }
    }
    func (c *MyConn )Read(...) {
    c.Conn.Read(...)
    if err {
    c.Close()
    }
    }
    On Tuesday, May 28, 2013 9:30:46 AM UTC+8, Dave Cheney wrote:

    This has been discussed several times on the mailing list, I suggest
    you search the archives. The summary is, you cannot tell if someone
    has closed the connection without doing a Read or Write call and
    responding to the error status.
    On Tue, May 28, 2013 at 11:28 AM, dlin wrote:
    I'm trying to recover a disconnected situation on client side. But I
    can
    not handle it well.

    1. I can not check connection property to make sure should I Close()

    if ! c.Closed() { // There is no Closed() function
    c.Close()
    }

    2. Is there faster method (eg. just call c.Write() to write block of
    struct
    memory?)


    // client code. If write failed, it will redial after 5 second
    package main

    import (
    "encoding/binary"
    "log"
    "net"
    "time"
    )

    const someTime = 5 * time.Second

    type IP4Addr struct {
    IP [4]byte
    Port uint16
    }
    type Command struct {
    IP4Addr
    CliConnSeq, SrvConnSeq uint32
    Id uint32 // srvId*100 + proxyId*10 + cliId
    Seq uint32 // srvSeq*10000 + cliSeq
    }

    func main() {
    var dummy Command
    L_DIAL:
    for {
    log.Println("Dialing")
    c, err := net.Dial("tcp", ":20000")
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue
    }
    for {
    err = binary.Write(c, binary.LittleEndian, dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    err = binary.Read(c, binary.LittleEndian, &dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    time.Sleep(time.Second)
    }
    }
    }

    --
    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...@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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...@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dlin at May 28, 2013 at 11:28 am
    In my previous code. There are two goroutines.
    One for send to net.Conn.
    Another for recv from net.Conn.

    If one Close() the net.Conn will that cause 'data race' problem?
    On Tuesday, May 28, 2013 10:32:07 AM UTC+8, Dave Cheney wrote:

    If you close the socket all reads and writes waiting will return io.EOF.

    On 28/05/2013, at 12:04, dlin <dli...@gmail.com <javascript:>> wrote:

    I'm sorry I can not explain the question well. So, I try to use code to
    explain.

    My problem is: I'm trying to implement a async protocol, one goroutine for
    Read, one goroutine for Write.
    When client try to Write()/Read() but fail, I'll return back to the main
    goroutine.
    If I don't know the status of Connection maybe one of the goroutine may
    hang forever.
    for example, sendCmdsToSrv call Write() and failed, it quit. But recvCmdsFromSrv()
    may still waiting response. So the WaitGroup still waiting.

    func srvService(srvAddr string) chan<- Command {
    c := make(chan Command, *maxCommands)
    go func(c chan Command) {
    for srvConnSeq := uint32(0); ; srvConnSeq++ {
    err := dialServer(srvConnSeq, &srvConn, srvAddr)
    if err != nil {
    break
    }
    var wg sync.WaitGroup
    wg.Add(2)
    go func() {
    sendCmdsToSrv(srvConn, srvConnSeq, c)
    wg.Done()
    }()
    go func() {
    recvCmdsFromSrv(srvConn, srvConnSeq, c)
    wg.Done()
    }()
    wg.Wait()
    }
    }(c)
    return c
    }

    On Tuesday, May 28, 2013 9:46:36 AM UTC+8, Dave Cheney wrote:

    Can you please describe the problem you are solving, not the solution
    you have come up with.
    On Tue, May 28, 2013 at 11:45 AM, dlin wrote:
    So, maybe one solution is writing a wrapper by myself?

    type MyConn struct {
    net.Conn
    opened bool
    }
    func (c *MyConn )Dial(...) {
    c.Conn.Dial(...)
    opened = true // if not err
    }
    func (c *MyConn )Close(...) {
    c.Conn.Close(...)
    opened = false
    }
    func (c *MyConn )Write(...) {
    c.Conn.Write(...)
    if err {
    c.Close()
    }
    }
    func (c *MyConn )Read(...) {
    c.Conn.Read(...)
    if err {
    c.Close()
    }
    }
    On Tuesday, May 28, 2013 9:30:46 AM UTC+8, Dave Cheney wrote:

    This has been discussed several times on the mailing list, I suggest
    you search the archives. The summary is, you cannot tell if someone
    has closed the connection without doing a Read or Write call and
    responding to the error status.
    On Tue, May 28, 2013 at 11:28 AM, dlin wrote:
    I'm trying to recover a disconnected situation on client side. But
    I
    can
    not handle it well.

    1. I can not check connection property to make sure should I Close()

    if ! c.Closed() { // There is no Closed() function
    c.Close()
    }

    2. Is there faster method (eg. just call c.Write() to write block of
    struct
    memory?)


    // client code. If write failed, it will redial after 5 second
    package main

    import (
    "encoding/binary"
    "log"
    "net"
    "time"
    )

    const someTime = 5 * time.Second

    type IP4Addr struct {
    IP [4]byte
    Port uint16
    }
    type Command struct {
    IP4Addr
    CliConnSeq, SrvConnSeq uint32
    Id uint32 // srvId*100 + proxyId*10 + cliId
    Seq uint32 // srvSeq*10000 + cliSeq
    }

    func main() {
    var dummy Command
    L_DIAL:
    for {
    log.Println("Dialing")
    c, err := net.Dial("tcp", ":20000")
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue
    }
    for {
    err = binary.Write(c, binary.LittleEndian, dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    err = binary.Read(c, binary.LittleEndian, &dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    time.Sleep(time.Second)
    }
    }
    }

    --
    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...@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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...@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/groups/opt_out.


    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dave Cheney at May 28, 2013 at 11:34 am
    No, not for net.Conn.Close(), multiple closers are expected and catered for. If you wrap the net.Conn in another type, no such guarantee exists.


    On 28/05/2013, at 21:28, dlin wrote:

    In my previous code. There are two goroutines.
    One for send to net.Conn.
    Another for recv from net.Conn.

    If one Close() the net.Conn will that cause 'data race' problem?
    On Tuesday, May 28, 2013 10:32:07 AM UTC+8, Dave Cheney wrote:

    If you close the socket all reads and writes waiting will return io.EOF.
    On 28/05/2013, at 12:04, dlin wrote:

    I'm sorry I can not explain the question well. So, I try to use code to explain.

    My problem is: I'm trying to implement a async protocol, one goroutine for Read, one goroutine for Write.
    When client try to Write()/Read() but fail, I'll return back to the main goroutine.
    If I don't know the status of Connection maybe one of the goroutine may hang forever.
    for example, sendCmdsToSrv call Write() and failed, it quit. But recvCmdsFromSrv() may still waiting response. So the WaitGroup still waiting.

    func srvService(srvAddr string) chan<- Command {
    c := make(chan Command, *maxCommands)
    go func(c chan Command) {
    for srvConnSeq := uint32(0); ; srvConnSeq++ {
    err := dialServer(srvConnSeq, &srvConn, srvAddr)
    if err != nil {
    break
    }
    var wg sync.WaitGroup
    wg.Add(2)
    go func() {
    sendCmdsToSrv(srvConn, srvConnSeq, c)
    wg.Done()
    }()
    go func() {
    recvCmdsFromSrv(srvConn, srvConnSeq, c)
    wg.Done()
    }()
    wg.Wait()
    }
    }(c)
    return c
    }

    On Tuesday, May 28, 2013 9:46:36 AM UTC+8, Dave Cheney wrote:

    Can you please describe the problem you are solving, not the solution
    you have come up with.
    On Tue, May 28, 2013 at 11:45 AM, dlin wrote:
    So, maybe one solution is writing a wrapper by myself?

    type MyConn struct {
    net.Conn
    opened bool
    }
    func (c *MyConn )Dial(...) {
    c.Conn.Dial(...)
    opened = true // if not err
    }
    func (c *MyConn )Close(...) {
    c.Conn.Close(...)
    opened = false
    }
    func (c *MyConn )Write(...) {
    c.Conn.Write(...)
    if err {
    c.Close()
    }
    }
    func (c *MyConn )Read(...) {
    c.Conn.Read(...)
    if err {
    c.Close()
    }
    }
    On Tuesday, May 28, 2013 9:30:46 AM UTC+8, Dave Cheney wrote:

    This has been discussed several times on the mailing list, I suggest
    you search the archives. The summary is, you cannot tell if someone
    has closed the connection without doing a Read or Write call and
    responding to the error status.
    On Tue, May 28, 2013 at 11:28 AM, dlin wrote:
    I'm trying to recover a disconnected situation on client side. But I
    can
    not handle it well.

    1. I can not check connection property to make sure should I Close()

    if ! c.Closed() { // There is no Closed() function
    c.Close()
    }

    2. Is there faster method (eg. just call c.Write() to write block of
    struct
    memory?)


    // client code. If write failed, it will redial after 5 second
    package main

    import (
    "encoding/binary"
    "log"
    "net"
    "time"
    )

    const someTime = 5 * time.Second

    type IP4Addr struct {
    IP [4]byte
    Port uint16
    }
    type Command struct {
    IP4Addr
    CliConnSeq, SrvConnSeq uint32
    Id uint32 // srvId*100 + proxyId*10 + cliId
    Seq uint32 // srvSeq*10000 + cliSeq
    }

    func main() {
    var dummy Command
    L_DIAL:
    for {
    log.Println("Dialing")
    c, err := net.Dial("tcp", ":20000")
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue
    }
    for {
    err = binary.Write(c, binary.LittleEndian, dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    err = binary.Read(c, binary.LittleEndian, &dummy)
    if err != nil {
    log.Println(err)
    time.Sleep(someTime)
    continue L_DIAL
    }
    time.Sleep(time.Second)
    }
    }
    }

    --
    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...@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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...@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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...@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • André Moraes at May 28, 2013 at 11:56 am

    On Tue, May 28, 2013 at 8:28 AM, dlin wrote:
    In my previous code. There are two goroutines.
    One for send to net.Conn.
    Another for recv from net.Conn.
    This talk could give you some help, the problem is similar

    http://www.youtube.com/watch?v=QDDwwePbDtw


    --
    André Moraes
    http://amoraes.info

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedMay 28, '13 at 1:28a
activeMay 28, '13 at 11:56a
posts9
users3
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase