network programming about go

820 views
Skip to first unread message

28911...@gmail.com

unread,
Oct 30, 2017, 2:55:27 AM10/30/17
to golang-nuts
I write this code in the follwings:
package main

import (
"fmt"
"net"
"os"
)

func main() {
service := ":5000"
tcpAddr, err := net.ResolveTCPAddr("tcp", service)
checkError(err)
listener, err := net.ListenTCP("tcp", tcpAddr)
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]))
_, err2 := conn.Write([]byte("welcome client!"))
if err2 != nil {
return
}
}
}
func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "fatal error: %s", err.Error())
os.Exit(1)
}
}


I try to run it in Sublime Text3 but it has no reaction and I try to run it in running windows, it shows:
fatal error: lsiten tcp:5000:bind:Only one usage of each socket address(protocol/network address/port) is normally permitted.exit status 1

28911...@gmail.com

unread,
Nov 2, 2017, 5:37:46 AM11/2/17
to golang-nuts
who can solve this problem?

在 2017年10月30日星期一 UTC+8下午2:55:27,28911...@gmail.com写道:

Justin Israel

unread,
Nov 2, 2017, 2:41:06 PM11/2/17
to 28911...@gmail.com, golang-nuts
It is a server program, waiting for connections from a client. When you say it has no reactions, does that mean it doesn't respond to client connections, or that it is not doing some other kind of expected behaviour when you run it? Can you be more specific about what you have tried, what you expected, and what actually happened? 

and I try to run it in running windows, it shows:
fatal error: lsiten tcp:5000:bind:Only one usage of each socket address(protocol/network address/port) is normally permitted.exit status 1

If your server program still running within SublimeText and listening on that port? 


--
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.

28911...@gmail.com

unread,
Nov 6, 2017, 2:53:50 AM11/6/17
to golang-nuts
Sorry, the last program is about server.and the following program is about the client:
   
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", os.Args[0])
    }
 service := os.Args[1]

 tcpAddr, err := net.ResolveTCPAddr("tcp", service)
 checkError(err)
 conn, err := net.DialTCP("tcp", nil, tcpAddr)
 checkError(err)
 rAddr := conn.RemoteAddr()
 n, err := conn.Write([]byte("hello server!"))
 checkError(err)

 n, err = conn.Read(buf[0:])
 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(0)
   }
}


the questoin is how to make the client communicate with the server??I want to see the message can be showed on the screen. Can these  programs  run in the same computer??if so,How to make it?? 

在 2017年10月30日星期一 UTC+8下午2:55:27,28911...@gmail.com写道:
I write this code in the follwings:

roger peppe

unread,
Nov 6, 2017, 4:08:26 AM11/6/17
to 28911...@gmail.com, golang-nuts
From that error message, I suspect that you already have a running instance
of your program - as the message says, you are only allowed to listen
on a port once.

To avoid that, you could listen on port zero, which will choose an arbitrary
port (but then you'll need to print out the port number so that you can
know which port to use on the client).

By the way, your code is a little bit more complex than
it needs to be. Instead of this:

> service := ":5000"
> tcpAddr, err := net.ResolveTCPAddr("tcp", service)
> checkError(err)
> listener, err := net.ListenTCP("tcp", tcpAddr)

You could do:

service := ":5000"
listener, err := net.Listen("tcp", tcpAddr)

Similarly when dialing - there's no need to call ResolveTCPAddr
explicitly (and it's actually not as good if you do that,
because Dial will automatically use multiple IP addresses
if it needs to, but if you use ResolveTCPAddr, it can only use one).

Hope this helps,

rog.

28911...@gmail.com

unread,
Nov 6, 2017, 9:00:22 AM11/6/17
to golang-nuts
I try to modify the program,but the result is: host:portfatal error: dial tcp 192.168.153.239:5000: connectex: No connection could be made because the target machine actively refused it.exit status 1.How to solve it??

在 2017年11月6日星期一 UTC+8下午5:08:26,rog写道:

Karan Chaudhary

unread,
Nov 7, 2017, 2:22:44 AM11/7/17
to golang-nuts
Is the port 5000 on 192.168.153.239 open?  If it is open,  is your server running on that port?

28911...@gmail.com

unread,
Nov 10, 2017, 8:22:34 AM11/10/17
to golang-nuts
I try to change the IP address and close the software related,but it sometimes still can't run sucessfully.Sometimes it can run parts of the result I hope to see.It shows that the client can connect with the server but the server can't connect the client and get the message.

在 2017年11月7日星期二 UTC+8下午3:22:44,Karan Chaudhary写道:

28911...@gmail.com

unread,
Nov 11, 2017, 3:55:04 AM11/11/17
to golang-nuts
 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??

Justin Israel

unread,
Nov 11, 2017, 4:04:10 PM11/11/17
to 28911...@gmail.com, golang-nuts
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 successful write, if you are choosing to do a request/reply pattern. 

Justin Israel

unread,
Nov 11, 2017, 4:05:49 PM11/11/17
to 28911...@gmail.com, golang-nuts
Thanks autocorrect. I have no problem with the elderly, but it has no business here in this response. 

28911...@gmail.com

unread,
Nov 12, 2017, 4:11:15 AM11/12/17
to golang-nuts
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.

在 2017年11月12日星期日 UTC+8上午5:05:49,Justin Israel写道:

Justin Israel

unread,
Nov 12, 2017, 1:32:47 PM11/12/17
to 28911...@gmail.com, golang-nuts


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. 

28911...@gmail.com

unread,
Nov 12, 2017, 10:00:26 PM11/12/17
to golang-nuts
I know your meaning.But I still can't get the result I want. 
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??



在 2017年11月13日星期一 UTC+8上午2:32:47,Justin Israel写道:

Justin Israel

unread,
Nov 13, 2017, 4:57:33 PM11/13/17
to 28911...@gmail.com, golang-nuts
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:

Client:

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?

as

unread,
Dec 1, 2017, 7:43:52 AM12/1/17
to golang-nuts
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. 
Reply all
Reply to author
Forward
0 new messages