CS 结构
BS 结构
网络编程的基本介绍
Golang的主要设计目标之一就是面向大规模后端服务程序,网络通信这块是服务端必不可少也是至关重要的一部分
网络编程有两种:
TCP socket编程 是网络编程的主流。之所以叫做 TCP socket编程,是因为底层是基于Tcp/ip 协议的 比如QQ聊天
b/s结构的 HTTP 编程 我们使用浏览器去访问服务器的时候,使用的就是HTTP协议,而HTTP低层依旧是用 tcp socket实现的 。比如 京东商城
TCP/IP 协议
这个协议是internet中最基本的协议
IP地址
每一个Internet的主机和路由器都有一个IP地址,他包括网络号和主机号 IP地址有ipv4 和 ipv6 可以通过ipconfig查看
端口介绍
我们这里所指的端口不是物理意义的端口,而是tcp/ip 协议中的端口,是逻辑意义上的端口
如果把ip地址比作一间房子,端口就是出入这间房子的门
一个ip地址的端口可以有65536(即 256*256)之多端口是通过端口号来标记的,端口号只有整数,范围从0-65536
端口分类
0 是保留端口
1-1024是固定端口 程序员不能用
1025-65535 程序员可以使用
tcp socket编程的快速入门
服务端的处理流程
1)监听端口
2)接收客户端的tcp连接,建立客户端和服务器端的连接
3)创建goroutine 处理该连接请求
客户端的处理流程
1 建立与服务端的连接
2 发送请求数据,接收服务器返回的结果数据
3 关闭连接
示意图
代码实现
程序框架图示意图
- 服务端功能:
编写一个服务端程序,在8888端口进行监听
可以和多个客户端创建连接
连接成功后,客户端可以发送数据,服务端接受数据,并显示在终端上
先试用telnet进行测试,然后编写客户端程序来测试
服务器端代码
package main
import (
"fmt"
"net"
) //做网络socket开发的时候 net包包含所有需要的函数和方法
func process(conn net.Conn) {
//这里循环的接受客户端发送的数据
defer conn.Close()//关闭
for {
//创建一个切片
buf := make([]byte,1024)
//conn.Read(buf)
//1 等待客户端通过conn发送信息
//2 如果客户端没有write[发送]那么协成就阻塞到这里
fmt.Printf("服务器再等待客户端%s发送信息\n",conn.RemoteAddr().String())
n,err := conn.Read(buf)
if err!= nil{
fmt.Println("服务器 read err= ",err)
return
}
// 显示客户端发送的内容到服务器的终端
fmt.Print(string(buf[:n]))
}
}
func main() {
fmt.Println("服务器开始监听了")
//net.Listen("tcp","0.0.0.0:8888")
//tcp 表示网络协议是tcp
// 0.0.0.0:8888 表示在本地监听 8888端口
lister,err := net.Listen("tcp","0.0.0.0:8888")
if err != nil{
fmt.Println("listen err =",err)
return
}
defer lister.Close() //延时关闭
//循环等待客户端来连接我
for{
//等 客户端来连接
fmt.Println("等客户端来连接。。。。。")
conn,err := lister.Accept()
if err != nil{
fmt.Println("Accpet err=",err)
}else {
fmt.Printf("accept suc conn = %v 客户端ip地址%v\n ",conn,conn.RemoteAddr().String())
}
go process(conn)
}
fmt.Printf("listen suc = %v\n",lister)
}
客户端功能
- 编写一个客户端程序,能连接到服务器端的8888端口上
- 客户端能发送单行数据,并退出
代码
package main
import (
"bufio"
"fmt"
"net"
"os"
)
func main() {
conn,err := net.Dial("tcp","0.0.0.0:8888")
if err != nil{
fmt.Println("client dial err=",err)
return
}
fmt.Println("conn 成功=",conn)
// 功能一 客户端可以发送单行数据 然后就退出
reader:= bufio.NewReader(os.Stdin) //os.Stdin 代表管理输入
//从终端读取一行数据 并准备发送给服务器
line,err := reader.ReadString('\n')
if err != nil{
fmt.Println("读取失败 err=",err)
}
//再将line 发送给服务器
n,err := conn.Write([]byte(line))
if err != nil{
fmt.Println("conn write err=",err)
}
fmt.Printf("客户端发送了 %d个字节数,并推出",n)
}
有疑问加站长微信联系(非本文作者)