TCP client/server program doesn't work

I can do a server program or a client program, but I don’t know how to do a client/server program. Does someone know what’s wrong with this code? Thanks.

package main

import (
	"net"
	"os"
	"bufio"
	"io"
)

func main() {
	listen, _ := net.Listen("tcp", "localhost:5431")


	dial, _ := net.Dial("tcp", "localhost:5432")


	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		conn, _ := listen.Accept()
		if scanner.Text() == "a"{
			conn.Close()
			listen.Close()
			dial.Close()
			break
		}
		dial.Write([]byte(scanner.Text()))

		io.Copy(os.Stdout, conn)
	}
}

Add error handling to your code. If any of the calls fails, the error message will help you finding out what went wrong.

1 Like

When I start the program It prints this error:
dial tcp [::1]:5432: connectex: No connection could be made because the target machine actively refused it.
and when I send something prints this error:
panic: runtime error: invalid memory address or nil pointer dereference

The first error message indicates that no process listens on port 5432. If I understand the first sentence of your original post correctly, your code shall play the role of both the sender and the receiver. In this case, the Listen() call should listen on 5432.
Also, move the Accept() call out of the loop as the code only creates a single connection.

I ran your code on my machine but I cannot replicate the second error. (But I also cannot make the program receive more than one line from stdin. Looks like io.Copy() keeps listening on conn.) As mentioned before, adding error handing will help tracking down errors.

1 Like
package main

import (
	"net"
	"os"
	"bufio"
	"fmt"
	"bytes"
)

func main() {
	listen, err := net.Listen("tcp", "localhost:9002")
	if err != nil{
		fmt.Println(err.Error())
	}


	dial, err := net.Dial("tcp", "localhost:9002")
	if err != nil{
		fmt.Println(err.Error())
	}

	scanner := bufio.NewScanner(os.Stdin)
	conn, err := listen.Accept()
	if err != nil{
		fmt.Println(err.Error())
	}
	for scanner.Scan() {
		if scanner.Text() == "a"{
			conn.Close()
			listen.Close()
			dial.Close()
			break
		}
		dial.Write([]byte(scanner.Text()))

		result := bytes.NewBuffer(nil)
		var buf [512]byte
		n, err := conn.Read(buf[0:])
		if err != nil{
			fmt.Println(err.Error())
		}
		result.Write(buf[0:n])
		fmt.Println(string(result.Bytes()))
	}
}

This works if I run only a program, but I want to run for example programA.go and programB.go for send and receive messages between them so I have to put 9001 port to listen and 9002 port to dial in programA.go and 9002 to listen and 9001 to dial in programB.go

With the last example if I put programA.go and programB.go in different folders, It works but I have to send from both to receive the message.
I want to see the message in the other program when I send something from anyone of both.

package main

import (
	"net"
	"sync"
	"log"
	"bufio"
	"os"
	"io"
)

var wg sync.WaitGroup

func main() {
	wg.Add(2)

	go func() {
		listen, err := net.Listen("tcp", "localhost:9001")
		if err != nil {
			log.Fatal(err)
		}
		defer listen.Close()

		for {
			conn, err := listen.Accept()
			defer conn.Close()
			if err != nil {
				log.Fatal(err)
			}

			io.Copy(os.Stdout, conn)

		}
	}()

	go func() {
		dial, err := net.Dial("tcp", "localhost:9002")
		if err != nil {
			log.Fatal(err)
		}
		defer dial.Close()
		scanner := bufio.NewScanner(os.Stdin)
		for scanner.Scan() {
			if scanner.Text() == "exit"{
				dial.Write([]byte("Your mate has left the room"))
				break
			}
			dial.Write([]byte(scanner.Text() + "\n"))
		}
	}()

	wg.Wait()
}

This works perfect :relaxed:

Good to hear that.

1 Like
package main

import (
	"net"
	"sync"
	"log"
	"bufio"
	"os"
	"io"
	"time"
)

func receiveConn() net.Conn {
	for{
		xx, err := net.Dial("tcp", "localhost:9002")
		if err == nil{
			return xx
		}
		time.Sleep(1 * time.Second)
	}
}

var wg sync.WaitGroup

func main() {
	wg.Add(2)

	go func() {
		listen, err := net.Listen("tcp", "localhost:9001")
		if err != nil {
			log.Fatal(err)
		}
		defer listen.Close()

		for {
			conn, err := listen.Accept()
			defer conn.Close()
			if err != nil {
				log.Fatal(err)
			}

			io.Copy(os.Stdout, conn)

		}
	}()

	go func() {
		dial := receiveConn()

		defer dial.Close()
		scanner := bufio.NewScanner(os.Stdin)
		for scanner.Scan() {
			if scanner.Text() == "exit"{
				dial.Write([]byte("Your mate has left the room"))
				break
			}
			dial.Write([]byte(scanner.Text() + "\n"))
		}
	}()

	wg.Wait()
}

Improved version.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.