I'm having trouble with socket programming.
I have a program that reads from localhost:7777 and writes to localhost:8000.
I use netcat
from the command line to write and read to 7777 and 8000 respectively.
This is the reader:
netcat -l -p 8000
And this is the writer:
printf "asti||" | netcat localhost 7777
But my program gets network errors when it tries to write to port 8000 for the second
time. The error is Fatal error: dial tcp 127.0.0.1:8000: getsockopt: connection refused
.
What's happening? Why on the second write the error appears?
Furthermore, I noticed that if I kill the netcat reader and restart it then there's no network errors. So to reiterate, the program writes once to 8000 and netcat reads it. Then I kill netcat reader and restart it. At this point the program can write again to 8000. But if the program tries to write two successive times to 8000 without me restarting netcat, then the error appears.
Here is the entire program (it's short). If you like, you experience this mystical behaviour yourself:
package main
import (
"fmt"
"net"
"os"
"strings"
// "io/ioutil"
)
func main() {
end_of_message_terminator := "||"
beginning_of_next_message := ""
request := make([]byte, 512)
service_port := ":7777"
tcpAddr, err := net.ResolveTCPAddr("tcp4", service_port)
checkError(err)
listener, err := net.ListenTCP("tcp", tcpAddr)
checkError(err)
for {
conn, err := listener.Accept()
if err != nil {
continue
}
read_len, err := conn.Read(request)
if read_len == 0 {
continue
}
request_string := string(request[:read_len])
fmt.Printf("Request String %s\\END", request_string)
messages := strings.Split(request_string, end_of_message_terminator)
fmt.Printf("%q
", messages)
messages[0] = beginning_of_next_message + messages[0]
if messages[len(messages) - 1] != "" {
beginning_of_next_message = messages[len(messages) - 1]
messages[len(messages) - 1] = ""
fmt.Printf("was here 00
")
}
if len(messages) == 1 {
continue
}
for i := range messages {
go func(){
fmt.Printf("was here 04
")
respond_to_message(messages[i])
}()
fmt.Printf("was here 01
")
}
conn.Close()
}
}
func respond_to_message(message string){
message_parameters := strings.Split(message, "|")
response_port := "localhost:8000"
tcpAddr_res, err := net.ResolveTCPAddr("tcp4", response_port)
checkError(err)
response_writer, err := net.DialTCP("tcp", nil, tcpAddr_res)
for i := range message_parameters {
fmt.Printf("was here03
")
param_parts := strings.Split(message_parameters[i], "=")
fmt.Printf("message: %s
", message)
fmt.Printf("message_parameters%q
", message_parameters)
fmt.Printf("params_parts: %q
", param_parts)
//param_name := param_parts[0]
//param_value := param_parts[1]
checkError(err)
response_writer.Write([]byte("asti de crhis"))
checkError(err)
//result, err := ioutil.ReadAll(response_writer)
//checkError(err)
//fmt.Println(string(result))
}
//response_writer.Close()
}
func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}
}