TCP doesn't preserve message delimiters. There is no guarantee that one write will be one read on the remote side even if they appear to be reading and writing in lockstep.
On Monday, November 13, 2017 at 1:57:33 PM UTC-8, Justin Israel wrote: > > > > On Mon, Nov 13, 2017 at 4:00 PM <28911...@gmail.com <javascript:>> wrote: > >> I know your meaning.But I still can't get the result I want. >> this is the server program: >> package main >> >> import ( >> "fmt" >> "net" >> "os" >> "strings" >> ) >> >> func main() { >> >> listener, err := net.Listen("tcp", "0.0.0.0:400") >> checkError(err) >> for i := 0; i < 10; i++ { >> conn, err := listener.Accept() >> if err != nil { >> continue >> } >> handleClient(conn) >> conn.Close() >> } >> } >> func handleClient(conn net.Conn) { >> var buf [512]byte >> for { >> n, err := conn.Read(buf[0:]) >> if err != nil { >> return >> } >> rAddr := conn.RemoteAddr() >> fmt.Println("receive from client:", rAddr.String(), string(buf[0:n])) >> aa := string("nice to meet you") >> _, err2 := conn.Write([]byte("welcome client!")) >> if strings.Contains(string(buf[0:n]), aa) { >> _, err2 = conn.Write([]byte("nice to meet you too")) >> } >> checkError(err2) >> n, err = conn.Read(buf[0:]) >> if err != nil { >> return >> } >> } >> } >> func checkError(err error) { >> if err != nil { >> fmt.Fprintf(os.Stderr, "fatal error: %s", err.Error()) >> os.Exit(1) >> } >> } >> >> >> this is the client program: >> package main >> >> import ( >> "fmt" >> "net" >> "os" >> ) >> >> func main() { >> var buf [512]byte >> if len(os.Args) != 2 { >> fmt.Fprintf(os.Stderr, "usage:%s host:port\n", os.Args[0]) >> } >> _, err := net.ResolveTCPAddr("tcp", "127.0.0.1:400") >> checkError(err) >> conn, err := net.Dial("tcp", "127.0.0.1:400") >> checkError(err) >> rAddr := conn.RemoteAddr() >> for { >> n, err := conn.Write([]byte("hello server!")) >> n, err = conn.Write([]byte(" nice to meet you")) >> checkError(err) >> n, err = conn.Read(buf[0:]) >> if err != nil { >> return >> } >> fmt.Println("reply from server:", rAddr.String(), string(buf[0:n])) >> n, err = conn.Read(buf[0:]) >> if err != nil { >> return >> } >> conn.Close() >> os.Exit(0) >> } >> } >> func checkError(err error) { >> if err != nil { >> fmt.Fprintf(os.Stderr, "fatal error: %s", err.Error()) >> os.Exit(1) >> } >> } >> >> >> The program still don't print "nice to meet you too". Can you help me >> modifying and writing down for me?? >> > > You have altered the client code to again write() two times in a row > without ready the response, thus it is possible for both the server and the > client to block. There should also not be a conditional write() in the > server. It should always be consistently request-reply. I've reformatted > your server and client code, trying to keep as much of your existing logic > as possible: > > Server: > https://play.golang.org/p/CeChTes_yv > > Client: > https://play.golang.org/p/CVfIpBhsiz > > There are better ways to write this, but just keeping it simple and close > to your original code you can see that the server is set up to first do a > handshake, and then goes into a loop where it reads requests and always > replies with something. Then the client does a couple request-reply > operations. There is always a matching read-write exchange going on. > > Hopefully this helps to clarify where you had made the error in your > original program? > > >> >> >> >> 在 2017年11月13日星期一 UTC+8上午2:32:47,Justin Israel写道: >> >>> >>> >>> On Sun, Nov 12, 2017, 10:11 PM <28911...@gmail.com> wrote: >>> >>>> So how to modify my program correctly??I try to add read in different >>>> place but it still can't get the result I want. >>>> >>> >>> Make sure your server is doing: >>> read, write, read, write >>> >>> And your client is doing: >>> write, read, write, read >>> >>> But honestly it becomes hard to keep track and line up the two when you >>> are complicating the server handler loop. Why not just simplify the server >>> so that it always just reads, checks the value and writes something back, >>> then loops again? And the client would make sure to always write and then >>> read. >>> You have a conditional write on the server so that means if a client >>> doesn't say the correct phrase, it won't know if reading afterwards is >>> going to block forever. >>> >>> >>>> 在 2017年11月12日星期日 UTC+8上午5:05:49,Justin Israel写道: >>>>> >>>>> >>>>> >>>>> On Sun, Nov 12, 2017, 10:03 AM Justin Israel <justin...@gmail.com> >>>>> wrote: >>>>> >>>> >>>>>> >>>>>> On Sat, Nov 11, 2017, 9:55 PM <28911...@gmail.com> wrote: >>>>>> >>>>>>> this is the server program: >>>>>>> >>>>>>>> package main >>>>>>>> >>>>>>>> import ( >>>>>>>> "fmt" >>>>>>>> "net" >>>>>>>> "os" >>>>>>>> >>>>>>> "strings" >>>>>>>> ) >>>>>>>> >>>>>>>> func main() { >>>>>>>> >>>>>>>> listener, err := net.Listen("tcp", "0.0.0.0:400") >>>>>>>> >>>>>>> checkError(err) >>>>>>>> for i := 0; i < 10; i++ { >>>>>>>> conn, err := listener.Accept() >>>>>>>> if err != nil { >>>>>>>> continue >>>>>>>> } >>>>>>>> handleClient(conn) >>>>>>>> conn.Close() >>>>>>>> } >>>>>>>> } >>>>>>>> func handleClient(conn net.Conn) { >>>>>>>> var buf [512]byte >>>>>>>> for { >>>>>>>> n, err := conn.Read(buf[0:]) >>>>>>>> if err != nil { >>>>>>>> return >>>>>>>> } >>>>>>>> rAddr := conn.RemoteAddr() >>>>>>>> fmt.Println("receive from client", rAddr.String(), string(buf[0:n])) >>>>>>>> >>>>>>> n, err2 := conn.Write([]byte("welcome client!")) >>>>>>>> >>>>>>> if err2 != nil { >>>>>>>> return >>>>>>>> } >>>>>>>> >>>>>>> aa := string("nice to meet you") >>>>>>>> if strings.Contains(string(buf[0:n]), aa) { >>>>>>>> n, err2 = conn.Write([]byte("nice to meet you too")) >>>>>>>> >>>>>>> if err2 != nil { >>>>>>>> return >>>>>>>> } >>>>>>>> } >>>>>>>> } >>>>>>>> } >>>>>>>> func checkError(err error) { >>>>>>>> if err != nil { >>>>>>>> fmt.Fprintf(os.Stderr, "fatal error: %s", err.Error()) >>>>>>>> os.Exit(1) >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>> >>>>>>>> >>>>>>> this is the client program: >>>>>>> package main >>>>>>> >>>>>>> import ( >>>>>>> "fmt" >>>>>>> "net" >>>>>>> "os" >>>>>>> ) >>>>>>> >>>>>>> func main() { >>>>>>> var buf [512]byte >>>>>>> if len(os.Args) != 2 { >>>>>>> fmt.Fprintf(os.Stderr, "usage:%s host:port\n", os.Args[0]) >>>>>>> } >>>>>>> _, err := net.ResolveTCPAddr("tcp", "127.0.0.1:400") >>>>>>> checkError(err) >>>>>>> conn, err := net.Dial("tcp", "127.0.0.1:400") >>>>>>> checkError(err) >>>>>>> rAddr := conn.RemoteAddr() >>>>>>> n, err := conn.Write([]byte("hello server!")) >>>>>>> checkError(err) >>>>>>> n, err = conn.Write([]byte(" nice to meet you")) >>>>>>> checkError(err) >>>>>>> n, err = conn.Read(buf[0:]) >>>>>>> if err != nil { >>>>>>> return >>>>>>> } >>>>>>> checkError(err) >>>>>>> fmt.Println("reply from server", rAddr.String(), string(buf[0:n])) >>>>>>> conn.Close() >>>>>>> os.Exit(0) >>>>>>> } >>>>>>> func checkError(err error) { >>>>>>> if err != nil { >>>>>>> fmt.Fprintf(os.Stderr, "fatal error: %s", err.Error()) >>>>>>> os.Exit(1) >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> >>>>>>> Just a little change and I run it successfully.But I am doubt why it >>>>>>> can't print "nice to meet you too"??And how to solve it?? >>>>>>> >>>>>> >>>>>> Your server does the following on a new connection >>>>>> >>>>>> n, err := conn.Read(buf[0:]) >>>>>> ... >>>>>> n, err2 := conn.Write([]byte("welcome client!")) >>>>>> >>>>>> Then your client is doing the following on the start of the >>>>>> connection >>>>>> >>>>>> n, err := conn.Write([]byte("hello server!")) >>>>>> ... >>>>>> >>>>>> n, err = conn.Write([]byte(" nice to meet you")) >>>>>> >>>>>> Both the client and server are blocking on writing and no one is >>>>>> doing any reading. Make sure your client does a read after elderly >>>>>> >>>>> >>>>> Thanks autocorrect. I have no problem with the elderly, but it has no >>>>> business here in this response. >>>>> >>>>> successful write, if you are choosing to do a request/reply pattern. >>>>>> >>>>> -- >>>>>>> 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/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...@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...@googlegroups.com <javascript:>. >> 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.