目录
01 06-socket-client-server通信过程分析
02 07-socket-server-单次处理
03 08-socket-client
01 09-socket-server-多连接建立
02 10-socket-client多次发送数据
01 -socket-client-server通信过程分析
### - Server Demo
接收一个链接,而且只能发送一次数据
```go
package main
import (
"fmt"
"net"
"strings"
)
func main() {
//创建监听
ip := "127.0.0.1"
port := 8848
address := fmt.Sprintf("%s:%d", ip, port)
//func Listen(network, address string) (Listener, error) {
//net.Listen("tcp", ":8848") //简写,冒号前面默认是本机: 127.0.0.1
listener, err := net.Listen("tcp", address)
if err != nil {
fmt.Println("net.Listen err:", err)
return
}
fmt.Println("监听中...")
//Accept() (Conn, error)
conn, err := listener.Accept()
if err != nil {
fmt.Println("listener.Accept err:", err)
return
}
fmt.Println("连接建立成功!")
//创建一个容器,用于接收读取到的数据
buf := make([]byte, 1024) //使用make来创建字节切片, byte ==> uint8
//Read(b []byte) (n int, err error)
//cnt:真正读取client发来的数据的长度
cnt, err := conn.Read(buf)
if err != nil {
fmt.Println("conn.Read err:", err)
return
}
fmt.Println("Client =====> Server, 长度:", cnt, ",数据:", string(buf[0:cnt]))
//服务器对客户端请求进行响应 ,将数据转成大写 "hello" ==> HELLO
//func ToUpper(s string) string {
upperData := strings.ToUpper(string(buf[0:cnt]))
//Write(b []byte) (n int, err error)
cnt, err = conn.Write([]byte(upperData))
fmt.Println("Client <====== Server, 长度:", cnt, ",数据:", upperData)
//关闭连接
conn.Close()
}
```

02 -socket-server-单次处理
### - client demo
```go
package main
import (
"fmt"
"net"
)
func main() {
conn, err := net.Dial("tcp", ":8848")
if err != nil {
fmt.Println("net.Dial err:", err)
return
}
fmt.Println("cliet与server连接建立成功!")
sendData := []byte("helloworld")
//向服务器发送数据
cnt, err := conn.Write(sendData)
if err != nil {
fmt.Println("conn.Write err:", err)
return
}
fmt.Println("Client ===> Server cnt:", cnt, ", data:", string(sendData))
//接收服务器返回的数据
//创建buf,用于接收服务器返回的数据
buf := make([]byte, 1024)
cnt, err = conn.Read(buf)
if err != nil {
fmt.Println("conn.Read err:", err)
return
}
fmt.Println("Client <==== Server , cnt:", cnt, ", data:", string(buf[0:cnt]))
conn.Close()
}
```


socket-server处理多个连接,每个连接可以接收多次数据

03 -socket-client
socket-server处理多个连接,每个连接可以接收多次数据
```go
package main
import (
"fmt"
"net"
"strings"
)
func main() {
//创建监听
ip := "127.0.0.1"
port := 8848
address := fmt.Sprintf("%s:%d", ip, port)
//func Listen(network, address string) (Listener, error) {
//net.Listen("tcp", ":8848") //简写,冒号前面默认是本机: 127.0.0.1
listener, err := net.Listen("tcp", address)
if err != nil {
fmt.Println("net.Listen err:", err)
return
}
//需求:
// server可以接收多个连接, ====> 主go程负责监听,子go程负责数据处理
// 每个连接可以接收处理多轮数据请求
for {
fmt.Println("监听中...")
//Accept() (Conn, error)
conn, err := listener.Accept()
if err != nil {
fmt.Println("listener.Accept err:", err)
return
}
fmt.Println("连接建立成功!")
go handleFunc(conn)
}
}
//处理具体业务的逻辑,需要将conn传递进来,每一新连接,conn是不同的
func handleFunc(conn net.Conn) {
for { //这个for循环,保证每一个连接可以多次接收处理客户端请求
//创建一个容器,用于接收读取到的数据
buf := make([]byte, 1024) //使用make来创建字节切片, byte ==> uint8
fmt.Println("准备读取客户端发送的数据....")
//Read(b []byte) (n int, err error)
//cnt:真正读取client发来的数据的长度
cnt, err := conn.Read(buf)
if err != nil {
fmt.Println("conn.Read err:", err)
return
}
fmt.Println("Client =====> Server, 长度:", cnt, ",数据:", string(buf[0:cnt]))
//服务器对客户端请求进行响应 ,将数据转成大写 "hello" ==> HELLO
//func ToUpper(s string) string {
upperData := strings.ToUpper(string(buf[0:cnt]))
//Write(b []byte) (n int, err error)
cnt, err = conn.Write([]byte(upperData))
fmt.Println("Client <====== Server, 长度:", cnt, ",数据:", upperData)
}
//关闭连接
_ = conn.Close()
}
```

04 -socket-server-多连接建立
当client多次发送数据时:

# 三、http
## 1. 概述
编写web语言:
1. java
2. php, 现在都在尝试使用go语言重写
3. python,豆瓣
4. go语言 ===》 beego,gin两个主流的web框架
https协议:我们使用浏览器访问的时候发送的就是http请求
1. http是应用层的协议,底层还是依赖传输层:tcp(短连接),网络层(ip)
2. 无状态的,每一次请求都是独立的,下次请求需要重新建立连接
3. https:
1. http是标准协议 ==》 明文传输,不安全
2. https不是标准协议 ===》 https = http + ssl(非对称加密,数字证书)--》加密的
3. 现在所有网站都会尽量要求使用https开发:安全
## 2. http请求报文格式
/day03-socket-http/assets/1575433140952.png)

05 -socket-client多次发送数据
一个http请求可以分为4部分:
1. 请求行:包含三部分
1. 格式: 方法 + URL + 协议版本号
2. 实例: POST + /chapter17/user + HTTP/1.1
3. 请求方法:
1. GET:获取数据
2. POST:上传数据(表单格式,json格式)
3. PUT:修改数据
4. DELETE: 用于删除数据
2. 请求头
1. 格式: key :value
2. 可以有很多个键值对(包含协议自带,也包含用户自定义的)
3. 常见重要头:
1. Accept : 接收数据的格式
2. User-Agent : 描述用户浏览器的信息
3. Connection: Keep-Alive (长链接), Close(短连接)
4. Aceept-Encoding : gzip, xxx , 描述可以接受的编码
5. Cookie: 由服务器设置的key=value数据,客户端下次请求的时候可以携带过来
6. Content-Type:
1. appliction/-form(表示上传的数据是表单格式),
2. application/json(表示body的数据是json格式)
7. 用户可以自定义的:
1. name : Duke
2. age : 18
3. 空行
1. 告诉服务器,请求头结束了,用于分割
4. 请求包体(可选的)
1. 一般在POST方法时,会配套提供BODY
2. 在GET的时候也可以提供BODY,但是这样容易让人混淆,建议不要这样使用
3. 上传两种数据格式:
1. 表单: 姓名,性别,年龄
2. json数据格式
启动tcp的server案例,使用postman发起http请求,查看http请求头信息:
```go
package main
import (
"fmt"
"net"
"strings"
)
func main() {
//创建监听
ip := "127.0.0.1"
port := 8848
address := fmt.Sprintf("%s:%d", ip, port)
//func Listen(network, address string) (Listener, error) {
//net.Listen("tcp", ":8848") //简写,冒号前面默认是本机: 127.0.0.1
listener, err := net.Listen("tcp", address)
if err != nil {
fmt.Println("net.Listen err:", err)
return
}
fmt.Println("server start ...")
//需求:
// server可以接收多个连接, ====> 主go程负责监听,子go程负责数据处理
// 每个连接可以接收处理多轮数据请求
for {
fmt.Println("监听中...")
//Accept() (Conn, error)
conn, err := listener.Accept()
if err != nil {
fmt.Println("listener.Accept err:", err)
return
}
fmt.Println("连接建立成功!")
go handleFunc(conn)
}
}



















