# 13.2 TCP 客户端

由于从之前的章节，您已经知道了，TCP 代表**传输控制协议**，并且它的主要特点是可靠性。每个包的 TCP 头部包含**源端口**和**目标端口**字段。这俩个字段，加上源和目标 IP 地址，组合成唯一标识单个 TCP 连接。这节实现的 TCP 客户端命名为 TCPclient.go，它由以下四部分构成。第一部分代码：

```go
package main

import (
    "bufio"
    "fmt"
    "net"
    "os"
    "strings"
)
```

第二部分代码：

```go
func main(){
    arguments := os.Args
    if len(arguments) == 1 {
        fmt.Println("Please provide host:port.")
        return
    }
    CONNECT := arguments[1]
    c, err := net.Dial("tcp", CONNECT)
    if err != nil {
        fmt.Println(err)
        return
    }
```

net.Dial() 方法连接远端服务器。这个方法的第一个参数定义使用的网络连接类型，第二个参数定义服务器地址，并且必须包含端口号。第一个参数的有效值为 tcp，tcp4 **(IPv4-only)**，tcp6 **(IPv6-ony)**，udp， udp4 **(IPv4-only)**，udp6 **(IPv6-only)**，ip，ip4 **(IPv4-only)**，ip6 **(IPv6-only)**，Unix **(Unix sockets)**，Unixgram 和 Unixpacket。

第三部分代码：

```go
for {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print(">> ")
    text, _ := reader.ReadString('\n')
    fmt.Fprintf(c, text + "\n")
```

前面这段代码用于从用户获取输入，使用 `os.Stdin` 文件进行验证读取。忽略从 `reader.ReadString()` 返回的 `error` 值不是一个好的实现，但它节省了空间。当然，你永远不要在正式软件中这样做。

最后一段代码：

```go
        message, _ := bufio.NewReader(c).ReadString('\n')
        fmt.Print("->: " + message)
        if strings.TrimSpace(string(text)) == "STOP" {
            fmt.Println("TCP client exiting...")
            return
        }
    }
}
```

为了测试，`TCPclient.go` 将连接由 `netcat(1)` 实现的TCP 服务器，它将产生以下输出：

```
$ go run TCPclient.go 8001
dial tcp: address 8001: missing port in address
$ go run TCPclient.go localhost:8001
>> Hello from TCPclient.go!
->: Hi from nc!

>> STOP
->:
TCP client exiting...
```

*请注意，给定协议如 TCP 和 UDP 的客户端本质上是可以通用的，这意味着它能够与支持其协议的多种服务器通信。您很快会看到，并不是使用指定协议的服务端应用必须实现指定的功能*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wskdsgcf.gitbook.io/mastering-go-zh-cn/13.0/13.2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
