社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
网络包发送解析基本过程:
osi七层在编程中可以简化为四层分别为:
实例:
标准输入代表键盘输入:
server.go
// net包提供了可移植的网络I/O接口,
// 包括TCP/IP、UDP、域名解析和Unix域socket
package main
import (
"fmt"
"net"
_"io"
)
func process(conn net.Conn){
// 循环接收客户发送的数据
defer conn.Close()
for {
buf := make([]byte,1024)
fmt.Println("服务器在等待客户端发送信息"+conn.RemoteAddr().String())
// Read从conn中读取数据返回n为此数据的长度
n,err := conn.Read(buf)
if err != nil{
fmt.Println("服务器端conn.Read err = :",err)
return
}
fmt.Print(string(buf[:n]))
}
}
func main(){
fmt.Println("服务器开始监听...")
// 返回在一个本地网络地址laddr上监听的Listener
// 网络类型参数net必须是面向流的网络:"tcp"、"tcp4"、"tcp6"
// "unix"或"unixpacket"
listen,err := net.Listen("tcp","0.0.0.0:8888")
defer listen.Close()
if err != nil{
fmt.Println("Listen err: ",err)
return
}
for {
fmt.Println("等待客户端来连接...")
conn,err := listen.Accept()
if err != nil{
fmt.Println("Accept() err:",err)
return
}else{
fmt.Printf("Accept() ok!=%v,client.address=%vn",conn,conn.RemoteAddr())
go process(conn)
}
}
}
client.go
package main
import (
"fmt"
"net"
"bufio"
"os"
)
func main(){
conn,err := net.Dial("tcp","127.0.0.1:8888")
if err != nil{
fmt.Println("Dial err:",err)
}
fmt.Println("连接成功! = ",conn)
// os.stdin 代表标准输入(终端)
reader := bufio.NewReader(os.Stdin)
// 从终端读取一行用户输入
line,err := reader.ReadString('n')
if err != nil{
fmt.Println("ReadString err:",err)
}
// 从连接中发送数据
n,err := conn.Write([]byte(line))
if err != nil{
fmt.Println("conn.Write err:",err)
}
fmt.Printf("客户端发送了 %d 个字节并退出",n)
}
ReadString()写入的数据是带n的有时候需要去掉就用下边这个函数
优化版本:
server.go
package main
import (
"fmt"
"net"
)
func con(conn net.Conn){
defer conn.Close()
// 定义一个1024长度的切片用来接收客户端的数据
// 循环从conn连接中读取信息
for {
buf := make([]byte,1024)
n,err := conn.Read(buf)
if err != nil{
fmt.Println("conn ")
}
fmt.Println("接收信息为: ")
fmt.Println(string(buf[:n]))
fmt.Println("等待连接")
}
}
func main(){
// 首先定义返回一个服务端的ip和端口
// 端口 0-65535
listen,err := net.Listen("tcp","0.0.0.0:9999")
if err != nil{
fmt.Println("listen err:",err)
}
// 循环接收client连接
for{
// 等待并返回一个连接到服务端地址ip的连接conn
conn,err := listen.Accept()
fmt.Println("连接建立fpx.no1")
defer conn.Close()
if err != nil{
fmt.Println("listen.Accept() err:",err)
}
go con(conn)
}
}
client.go
package main
import (
"fmt"
"net"
"bufio"
"os"
"strings"
)
func main(){
// Dial在指定的网络上连接指定的地址。参见Dial函数获取网络和地址参数的描述。
conn,err := net.Dial("tcp","0.0.0.0:9999")
if err != nil{
fmt.Println("net.Dial err:",err)
}
// NewReader创建一个缓冲区os.Stdin为标准输入(键盘输入)
fmt.Println("请写入将要发送给server的数据fpx.no1")
// 创建一个缓冲区
reader := bufio.NewReader(os.Stdin)
for {
line, err := reader.ReadString('n')
// 使用ReadString写入的数据是带有空格或者换行符的需要去掉方便判断
// strings.Trim() 返回将s前后端所有cutset包含的utf-8码值都去掉的字符串。
line = strings.Trim(line," rn")
if line == "exit"{
fmt.Println("退出```")
// return 退出当前函数 break退出当前循环
return
}
if err != nil{
fmt.Println("reader.ReadString() err:",err)
}
fmt.Println("即将发送fpx.no1")
n,err := conn.Write([]byte(line))
if err != nil{
fmt.Println("conn.Write() err:",err)
}
fmt.Printf("发送完毕,发送信息长度%d字节n",n)
}
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!