Tcp服务端客户端go编写
S端
func process(conn net.Conn) {
defer conn.Close()
for {
reader := bufio.NewReader(conn) //创建一个带有缓冲区的读取器
var buf [128]byte
n, err := reader.Read(buf[:]) //读取数据
if err != nil {
fmt.Println("read from C failed : ", err)
break
}
recvstr := string(buf[:n])
fmt.Println("收到clinet发来的数据:", recvstr)
conn.Write([]byte(recvstr)) //发送数据
}
}
func main() {
listen, err := net.Listen("tcp", "127.0.0.1:20000")
if err != nil {
fmt.Println("listen failed :", err)
return
}
for {
conn, err := listen.Accept()
if err != nil {
fmt.Println("accept failed :", err)
continue
}
go process(conn)
}
}
C端
package main
import (
"bufio"
"fmt"
"net"
"os"
"strings"
)
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:20000")
if err != nil {
fmt.Println("err :", err)
return
}
defer conn.Close() // 关闭连接
inputReader := bufio.NewReader(os.Stdin)
for {
input, _ := inputReader.ReadString('\n') // 读取用户输入
inputInfo := strings.Trim(input, "\r\n")
if strings.ToUpper(inputInfo) == "Q" { // 如果输入q就退出
return
}
_, err = conn.Write([]byte(inputInfo)) // 发送数据 //先转换为字节数组
if err != nil {
return
}
buf := [512]byte{}
n, err := conn.Read(buf[:])
if err != nil {
fmt.Println("recv failed, err:", err)
return
}
fmt.Println(string(buf[:n]))
}
}
UDP服务器客户端go编写
func main() {
listen, err := net.ListenUDP("udp", &net.UDPAddr{
IP: net.IPv4(0, 0, 0, 0),
Port: 30000,
})
if err != nil {
fmt.Println("listen is failed:", err)
return
}
defer listen.Close()
for {
var data [1024]byte //字节数组
n, addr, err := listen.ReadFromUDP(data[:]) //接收数据 读取的字节数
//数据来源的地址,可能发生的错误
if err != nil {
fmt.Println("read udp failed:", err)
continue
}
fmt.Printf("data:%v addr:%v count:%v\n", string(data[:]), addr, n)
_, err = listen.WriteToUDP(data[:], addr) //发送数据
if err != nil {
fmt.Println("write to udp failed:", err)
continue
}
}
}
UDP客户端代码
func main() {
socket, err := net.DialUDP("udp", nil, &net.UDPAddr{
IP: net.IPv4(0, 0, 0, 0),
Port: 30000,
})
if err != nil {
fmt.Println("连接服务器失败:", err)
return
}
defer socket.Close()
sendData := []byte("Hello Server")
_, err = socket.Write(sendData) //发送数据
if err != nil {
fmt.Println("数据发送失败", err)
return
}
data := make([]byte, 4000)
n, remoteAddr, err := socket.ReadFromUDP(data) //接收数据
if err != nil {
fmt.Println("接收数据失败", err)
return
}
fmt.Printf("recv:%v addr:%v count:%v\n", string(data[:]), remoteAddr, n)
}
TCP粘包处理
func Encode(message string) ([]byte, error) {
var length = int32(len(message))
var pkg = new(bytes.Buffer) //创建存储二进制的字节缓冲区
//将给定的数据按照给定的字节序写入到缓冲区中
err := binary.Write(pkg, binary.LittleEndian, length)
if err != nil {
return nil, err
}
return pkg.Bytes(), nil //缓冲区内容以字节数组返回
}
func Decode(reader *bufio.Reader) (string, error) {
lengthByte, _ := reader.Peek(4) //读取前四个字节的内容
lengthBuff := bytes.NewBuffer(lengthByte)
var length int32
err := binary.Read(lengthBuff, binary.LittleEndian, &length)
if err != nil {
return "", err
}
//Buffered返回缓冲区中现有的可读取的字节数
//检查缓冲区中是否有足够的数据用于读取整个消息
if int32(reader.Buffered()) < length+4 {
return "", err
}
//读取真正的消息数据 包括长度字段本身
pack := make([]byte, int(4+length))
_, err = reader.Read(pack)
if err != nil {
return "", err
}
//返回去除长度字段后的消息内容
return string(pack[:]), nil
}
针对上面的解码编码的S和C如下S:
func process(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
for {
msg, err := Decode(reader)
if err == io.EOF {
return
}
if err != nil {
fmt.Println("decode msg failed :", err)
return
}
fmt.Println("收到Client端发送的数据:", msg)
}
}
func main() {
listen, err := net.Listen("tcp", "127.0.0.1:30000")
if err != nil {
fmt.Println("listen failed : ", err)
return
}
defer listen.Close()
for {
conn, err := listen.Accept()
if err != nil {
fmt.Println("accept is failed", err)
return
}
go process(conn)
}
}
c:
func main(){
conn,err :=net.Dial("tcp","127.0.0.1:30000")
if err!=nil{
fmt.Println("dial failed :",err)
return
}
defer conn.Close()
for i:=0;i<20;i++{
msg:="Hello"
data,err:=Encode(msg)
if err!=nil{
fmt.Println("encode msg failed :",err)
return
}
conn.Write(data)
}
}