Update 15.1.md

修复部分格式
增加练习15.1的链接
This commit is contained in:
glight2000
2015-12-10 12:34:20 +08:00
parent 7485bf8ddc
commit fb61970fd1

View File

@@ -183,7 +183,7 @@ func main() {
con.Close() con.Close()
} }
``` ```
**练习 15.1** 编写新版本的客户端和服务器client1.to / server1.go **练习 15.1** 编写新版本的客户端和服务器([client1.to](exercises/chapter_15/client1.go) / [server1.go](exercises/chapter_15/server1.go)
* 增加一个检查错误的函数`checkError(error)`讨论如下方案的利弊为什么这个重构可能并没有那么理想看看在示例15.14中它是如何被解决的 * 增加一个检查错误的函数`checkError(error)`讨论如下方案的利弊为什么这个重构可能并没有那么理想看看在示例15.14中它是如何被解决的
* 使客户端可以通过发送一条命令SH来关闭服务器 * 使客户端可以通过发送一条命令SH来关闭服务器
* 让服务器可以保存已经连接的客户端列表他们的名字当客户端发送WHO指令的时候服务器将显示如下列表 * 让服务器可以保存已经连接的客户端列表他们的名字当客户端发送WHO指令的时候服务器将显示如下列表
@@ -286,8 +286,7 @@ func checkError(error error, info string) {
(**译者注应该是由于go版本的更新会提示os.EAGAIN undefined ,修改后的代码:[simple_tcp_server_v1.go](examples/chapter_15/simple_tcp_server_v1.go)**) (**译者注应该是由于go版本的更新会提示os.EAGAIN undefined ,修改后的代码:[simple_tcp_server_v1.go](examples/chapter_15/simple_tcp_server_v1.go)**)
都有哪些改进? 都有哪些改进?
* 服务器地址和端口不再是硬编码,而是通过命令行传入参数并通过`flag`包来读取这些参数。这里使用了`flag.NArg()`检查是否按照期望传入了2个参数
1服务器地址和端口不再是硬编码而是通过命令行传入参数并通过`flag`包来读取这些参数。这里使用了`flag.NArg()`检查是否按照期望传入了2个参数
```go ```go
if flag.NArg() != 2{ if flag.NArg() != 2{
panic("usage: host port") panic("usage: host port")
@@ -297,11 +296,11 @@ func checkError(error error, info string) {
```go ```go
hostAndPort := fmt.Sprintf("%s:%s", flag.Arg(0), flag.Arg(1)) hostAndPort := fmt.Sprintf("%s:%s", flag.Arg(0), flag.Arg(1))
``` ```
2`initServer`函数中通过`net.ResolveTCPAddr`指定了服务器地址和端口,这个函数最终返回了一个`*net.TCPListener` * `initServer`函数中通过`net.ResolveTCPAddr`指定了服务器地址和端口,这个函数最终返回了一个`*net.TCPListener`
3每一个连接都会以携程的方式运行`connectionHandler`函数。这些开始于当通过`conn.RemoteAddr()`获取到客户端的地址 * 每一个连接都会以携程的方式运行`connectionHandler`函数。这些开始于当通过`conn.RemoteAddr()`获取到客户端的地址
4它使用`conn.Write`发送改进的go-message给客户端 * 它使用`conn.Write`发送改进的go-message给客户端
5它使用一个25字节的缓冲读取客户端发送的数据并一一打印出来。如果读取的过程中出现错误代码会进入`switch`语句的`default`分支关闭连接。如果是操作系统的`EAGAIN`错误,它会重试。 * 它使用一个25字节的缓冲读取客户端发送的数据并一一打印出来。如果读取的过程中出现错误代码会进入`switch`语句的`default`分支关闭连接。如果是操作系统的`EAGAIN`错误,它会重试。
6所有的错误检查都被重构在独立的函数'checkError'中,用来分发出现的上下文错误。 * 所有的错误检查都被重构在独立的函数'checkError'中,用来分发出现的上下文错误。
在命令行中输入`simple_tcp_server localhost 50000`来启动服务器程序然后在独立的命令行窗口启动一些client.go的客户端。当有两个客户端连接的情况下服务器的典型输出如下这里我们可以看到每个客户端都有自己的地址 在命令行中输入`simple_tcp_server localhost 50000`来启动服务器程序然后在独立的命令行窗口启动一些client.go的客户端。当有两个客户端连接的情况下服务器的典型输出如下这里我们可以看到每个客户端都有自己的地址
``` ```
@@ -320,6 +319,7 @@ package net
type Error interface{ type Error interface{
Timeout() bool // 错误是否超时 Timeout() bool // 错误是否超时
Temporary() bool // 是否是临时错误 Temporary() bool // 是否是临时错误
}
``` ```
通过类型断言,客户端代码可以用来测试`net.Error`,从而区分哪些临时发生的错误或者必然会出现的错误。举例来说,一个网络爬虫程序在遇到临时发生的错误时可能会休眠或者重试,如果是一个必然发生的错误,则他会放弃继续执行。 通过类型断言,客户端代码可以用来测试`net.Error`,从而区分哪些临时发生的错误或者必然会出现的错误。举例来说,一个网络爬虫程序在遇到临时发生的错误时可能会休眠或者重试,如果是一个必然发生的错误,则他会放弃继续执行。
```go ```go