我正在尝试构建一个非常简单的tcp服务器/客户端。我希望程序可以在ctrl-c中断时关闭连接。
如果我只在主线程中发送消息或仅接收消息,一切正常。
以下是客户端的代码。
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"net"
"bufio"
"io"
"time"
)
const (
TIMEOUT = 10
)
func main() {
if len(os.Args) < 2 {
fmt.Println(usage(os.Args[0]))
return
}
var timeout time.Duration
if len(os.Args) > 2 {
timeout, _ = time.ParseDuration(os.Args[2])
}
if timeout == 0 {
timeout = time.Duration(TIMEOUT * time.Second)
}
conn, err := net.DialTimeout("tcp", os.Args[1], timeout)
if err != nil {
fmt.Println("Error connecting: ", err.Error())
return
}
defer conn.Close()
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
go func() {
fmt.Println("wait ctrl-c")
for _ = range c {
fmt.Println("close on ctrl-c")
conn.Close()
}
}()
for {
message, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err == io.EOF {
fmt.Fprint(conn, message)
break
} else if err != nil {
fmt.Println("Error reading: ", err.Error())
break
} else {
fmt.Fprintf(conn, message)
}
}
}
func usage(filename string) string {
return fmt.Sprintf("Usage: %s <address (ex. localhost:8016, google.com:http, [2001:db8::1]:http, etc.)> [timeout (ex. 10s, 300ms, etc.)]", filename)
}
但是在我添加了只打印它收到的代码并在另一个线程中运行它之后,ctrl-c处理程序不起作用。
这是代码:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"net"
"bufio"
"io"
"time"
)
const (
TIMEOUT = 10
)
func main() {
if len(os.Args) < 2 {
fmt.Println(usage(os.Args[0]))
return
}
var timeout time.Duration
if len(os.Args) > 2 {
timeout, _ = time.ParseDuration(os.Args[2])
}
if timeout == 0 {
timeout = time.Duration(TIMEOUT * time.Second)
}
conn, err := net.DialTimeout("tcp", os.Args[1], timeout)
if err != nil {
fmt.Println("Error connecting: ", err.Error())
return
}
defer conn.Close()
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
go func() {
fmt.Println("wait ctrl-c")
for _ = range c {
fmt.Println("close on ctrl-c")
conn.Close()
}
}()
// code added.
go func() {
for {
message, err := bufio.NewReader(conn).ReadString('\n')
if err == io.EOF {
fmt.Print(message)
break
} else if err != nil {
fmt.Println("Error remote reading: ", err.Error())
break
} else {
fmt.Print(message)
}
}
conn.Close()
os.Exit(0)
}()
for {
message, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err == io.EOF {
fmt.Fprint(conn, message)
break
} else if err != nil {
fmt.Println("Error reading: ", err.Error())
break
} else {
fmt.Fprintf(conn, message)
}
}
}
func usage(filename string) string {
return fmt.Sprintf("Usage: %s <address (ex. localhost:8016, google.com:http, [2001:db8::1]:http, etc.)> [timeout (ex. 10s, 300ms, etc.)]", filename)
}
我现在正在使用Windows 7。 有什么问题,如何解决?
您可以在此处找到服务器端和客户端代码: https://gist.github.com/programus/52591a97def30df9dc81