@@ -226,6 +226,76 @@ Go语言中通过net包中的`DialTCP`函数来建立一个TCP连接,并返回
226226
227227通过把业务处理分离到函数` handleClient ` ,我们就可以进一步地实现多并发执行了。看上去是不是很帅,增加` go ` 关键词就实现了服务端的多并发,从这个小例子也可以看出goroutine的强大之处。
228228
229+ 有的朋友可能要问:这个服务端没有处理客户端实际请求的内容。如果我们需要通过从客户端发送不同的请求来获取不同的时间格式,而且需要一个长连接,该怎么做呢?请看:
230+
231+ package main
232+
233+ import (
234+ "fmt"
235+ "net"
236+ "os"
237+ "time"
238+ "strconv"
239+ )
240+
241+ func main() {
242+ service := ":1200"
243+ tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
244+ checkError(err)
245+ listener, err := net.ListenTCP("tcp", tcpAddr)
246+ checkError(err)
247+ for {
248+ conn, err := listener.Accept()
249+ if err != nil {
250+ continue
251+ }
252+ go handleClient(conn)
253+ }
254+ }
255+
256+ func handleClient(conn net.Conn) {
257+ conn.SetReadDeadline(time.Now().Add(2 * time.Minute)) // set 2 minutes timeout
258+ request := make([]byte, 128) // set maxium request length to 128KB to prevent flood attack
259+
260+ for {
261+ read_len, err := conn.Read(request)
262+
263+ if err != nil {
264+ if err != io.EOF { // ignore EOF since client might send nothing for the moment
265+ fmt.Println(err)
266+ break
267+ }
268+
269+ neterr, ok := err.(net.Error)
270+ if ok && neterr.Timeout() {
271+ fmt.Println(neterr)
272+ break
273+ }
274+ }
275+
276+ if read_len == 0 {
277+ continue
278+ } else if string(request) == "timestamp" {
279+ daytime := strconv.FormatInt(time.Now().Unix(), 10)
280+ conn.Write([]byte(daytime))
281+ } else {
282+ daytime := time.Now().String()
283+ conn.Write([]byte(daytime))
284+ }
285+
286+ request = make([]byte, 128) // clear last read content
287+ }
288+ }
289+
290+ func checkError(err error) {
291+ if err != nil {
292+ fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
293+ os.Exit(1)
294+ }
295+ }
296+
297+ 在上面这个例子中,我们使用` conn.Read() ` 不断读取客户端发来的请求。由于我们需要保持与客户端的长连接,所以不能在读取完一次请求后就关闭连接。由于` conn.SetReadDeadline() ` 设置了超时,当一定时间内客户端无请求发送,` conn ` 便会自动关闭,下面的for循环即会因为连接已关闭而跳出。需要注意的是,` request ` 在创建时需要指定一个最大长度以防止flood attack;每次读取到请求处理完毕后,需要清理request,因为` conn.Read() ` 会将新读取到的内容append到原内容之后。
298+
229299### 控制TCP连接
230300TCP有很多连接控制函数,我们平常用到比较多的有如下几个函数:
231301
0 commit comments