Go语言中TCP/IP网络编程的深入讲解

2020-01-28 13:01:56于丽

客户端函数在执行应用程序时指定connect标志的时候执行,这点后面的代码可以看到。

下面是服务端程序server。服务端监听进来的请求并根据请求命令名将它们调度给注册的具体相关处理器。


func server() error {
 endpoint := NewEndpoint()
 // 添加处理器函数
 endpoint.AddHandleFunc("STRING", handleStrings)
 endpoint.AddHandleFunc("GOB", handleGOB)
 // 开始监听
 return endpoint.Listen()
}

main函数

下面的main函数既可以启动客户端也可以启动服务端, 依赖于是否设置connect标志。 如果没有这个标志,则以服务器启动进程, 监听进来的请求。如果有标志, 启动为客户端,并连接到这个标志指定的主机。

可以使用localhost或127.0.0.1在同一机器上运行这两个进程。


func main() {
 connect := flag.String("connect", "", "IP address of process to join. If empty, go into the listen mode.")
 flag.Parse()
 // 如果设置了connect标志,进入客户端模式
 if *connect != '' {
  err := client(*connect)
  if err != nil {
   log.Println("Error:", errors.WithStack(err))
  }
  log.Println("Client done.")
  return
 }
 // 否则进入服务端模式
 err := server()
 if err != nil {
  log.Println("Error:", errors.WithStack(err))
 }
 log.Println("Server done.")
}

// 设置日志记录的字段标志
func init() {
 log.SetFlags(log.Lshortfile)
}

如何获取并运行代码

第一步: 获取代码。 注意-d标志自动安装二进制到$GOPATH/bin目录。


go get -d github.com/appliedgo/networking

第二步: cd到源代码目录。


cd $GOPATH/src/github.com/appliedgo/networking

第三步: 运行服务端。


go run networking.go

第四步: 打开另外一个shell, 同样进入到源码目录(第二步), 然后运行客户端。


go run networking.go -connect localhost

Tips

如果你想稍微修改下源代码,下面是一些建议:

在不同机器运行客户端和服务端(同一个局域网中). 用更多的映射和指针来增强(beef up)complexData, 看看gob如何应对它(cope with it)。 同时启动多个客户端,看看服务端是否能处理它们。

2017-02-09: map不是线程安全的,因此如果在不同的goroutine中使用同一个map, 应该使用互斥锁来控制map的访问。
而上面的代码,map在goroutine启动之前已经添加好了, 因此你可以安全的修改代码,在handleMessages goroutine已经运行的时候调用AddHandleFunc()。

本章所学知识点总结

bufio的应用。 gob的应用。 map在多goroutine间共享时是不安全的。

参考链接

TCP/IP网络原文 简单的TCP服务端和客户端 gob数据