我遇到套接字编程问题。
我有一个程序从localhost:7777读取并写入localhost:8000。
我使用命令行中的netcat
分别写入和读取7777和8000.
这是读者:
netcat -l -p 8000
这是作家:
printf "asti||" | netcat localhost 7777
但我的程序在第二次尝试写入端口8000时会出现网络错误
时间。错误是Fatal error: dial tcp 127.0.0.1:8000: getsockopt: connection refused
。
发生了什么事?为什么在第二次写入错误出现?
此外,我注意到如果我杀死netcat阅读器并重新启动它,那么就没有网络错误。重申一下,程序写入一次到8000,netcat读取它。然后我杀死netcat阅读器并重新启动它。此时程序可以再次写入8000.但是如果程序尝试连续两次写入8000而没有重新启动netcat,则会出现错误。
这是整个程序(简称)。如果你愿意,你自己会体验到这种神秘的行为:
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\n", 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\n")
}
if len(messages) == 1 {
continue
}
for i := range messages {
go func(){
fmt.Printf("was here 04\n")
respond_to_message(messages[i])
}()
fmt.Printf("was here 01\n")
}
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\n")
param_parts := strings.Split(message_parameters[i], "=")
fmt.Printf("message: %s\n", message)
fmt.Printf("message_parameters%q\n", message_parameters)
fmt.Printf("params_parts: %q\n", 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)
}
}