我用golang做了个简单的tcp服务器,在这个基础上加了个http服务器,下面是个demo。这里没有考虑超时之类的,只是演示作用,下面是源码部分:
```go
package main
import (
"fmt"
"net"
"os"
)
func main() {
l, err := net.Listen("tcp", "localhost:9765")
if err != nil {
fmt.Println("Error listening:", err.Error())
os.Exit(1)
}
defer l.Close()
for {
conn, err := l.Accept()
fmt.Println("New connection...")
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
go handleRequest(conn)
}
}
// 响应
func handleRequest(conn net.Conn) {
for {
buf := make([]byte, 512)
_, err := conn.Read(buf)
if err != nil {
fmt.Println("Error reading:", err.Error())
conn.Close()
break
}
fmt.Printf("%s", buf)
str := `HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 8
Content-Type: application/javascript
alert(1)
`
conn.Write([]byte(str))
}
}
```
注意,我这里显示告诉客户端是需要keep-alive的,我写了个简单的html文件,如下所示:
```go
<!DOCTYPE html>
<html style="width:100%;height:100%" id="app" lang="zh-CN">
<head>
<meta charset="UTF-8">
<script type=text/javascript src="http://localhost:9765/3"></script>
<script type=text/javascript src="http://localhost:9765/2"></script>
<script type=text/javascript src="http://localhost:9765/1"></script>
</head>
<body>
<h1>loader测试页面</h1>
<span>hello world</span>
</body>
</html>
```
用nginx托管起来,在chrome里访问,我期望的是三次http请求公用一个tcp连接的,但是实际上发现这里建立了三个tcp连接,而且每个连接响应完了以后浏览器就主动关闭掉了tcp连接。按说我在响应头里加了connection: keep-alive,客户端应该识别出来,然后保持tcp连接才对啊。(这里判断客户端关闭的依据是服务端收到了EOF的错误)
下面是chrome的network的截图,看着也没啥问题:
![image.png](https://static.studygolang.com/190213/9056ba5b4120eb0ccb998b2fa6d0c38e.png)
更多评论
这里不要担心浏览器会一次性建多个tcp连接加快速度,chrome默认限制是6个,我加了十几个连接的时候会分多批去发请求,但是最后总的请求数是等于链接的数目的。
#1