Server端常用函数、接口:
Listen函数:
func Listen(network, address string) (Listener, error)
network:选用的协议:TCP、UDP, 如:“tcp”或 “udp”
address:IP地址+端口号, 如:“127.0.0.1:8000”或 “:8000”
Listener 接口:
type Listener interface {
Accept() (Conn, error)
Close() error
Addr() Addr
}
Conn 接口:
type Conn interface {
Read(b []byte) (n int, err error)
Write(b []byte) (n int, err error)
Close() error
LocalAddr() Addr
RemoteAddr() Addr
SetDeadline(t time.Time) error
SetReadDeadline(t time.Time) error
SetWriteDeadline(t time.Time) error
}
TCP-服务端实现:
func main() {
listen, err := net.Listen("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("net.Listen出错:", err)
return
}
defer listen.Close()
fmt.Println("服务器启动完毕,等待客户端连接")
accept, err := listen.Accept()
if err != nil {
fmt.Println("listen.Accept出错:", err)
return
}
defer accept.Close()
fmt.Println("服务器与客户端连接成功")
buf := make([]byte, 4096)
read, err := accept.Read(buf)
if err != nil {
fmt.Println("accept.Read出错:", err)
return
}
fmt.Println("服务器获取到:", string(buf[:read]))
}
Mac可以通过netcat进行测试:
TCP-客户端实现:
func main() {
dial, err := net.Dial("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("net.Dial出错:", err)
return
}
defer dial.Close()
dial.Write([]byte("我是客户端"))
buf := make([]byte, 4096)
read, err := dial.Read(buf)
if err != nil {
fmt.Println("accept.Read出错:", err)
return
}
fmt.Println("客户端获取到:", string(buf[:read]))
}
TCP实现并发-服务器:
上面都是单机版的客户端通信,如果想要实现并发,需要使用Goroutine+循环实现
- 循环读取客户端发送的数据
- 如果客户端强制关闭连接需要做处理
- 客户端发送exit时
演示:
package main
import (
"fmt"
"net"
"strings"
)
func main() {
listen, err := net.Listen("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("net.Listen出错:", err)
return
}
defer listen.Close()
fmt.Println("服务器启动成功,等待客户端连接!")
for {
accept, err := listen.Accept()
if err != nil {
fmt.Println("listen.Accept出错:", err)
return
}
go HandlerConnect(accept)
}
}
func HandlerConnect(accept net.Conn) {
defer accept.Close()
addr := accept.RemoteAddr()
fmt.Println(addr, "客户端连接成功!")
buf := make([]byte, 4096)
for {
read, err := accept.Read(buf)
if err != nil {
fmt.Println("accept.Read出错:", err)
return
}
fmt.Println("服务器读到数据:", string(buf[:read]))
data := strings.ToUpper(string(buf[:read]))
accept.Write([]byte(data))
}
}
TCP实现并发-客户端:
演示:
package main
import (
"fmt"
"net"
"os"
)
func main() {
dial, err := net.Dial("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("et.Dial出错了", err)
return
}
defer dial.Close()
go func() {
str := make([]byte, 4096)
for {
read, err := os.Stdin.Read(str)
if err != nil {
fmt.Println("os.Stdin.Read出错了", err)
continue
}
dial.Write(str[:read])
}
}()
buf := make([]byte, 4096)
for {
read, err := dial.Read(buf)
if read == 0 {
fmt.Println("检测到服务端端已经断开连接!")
return
}
if err != nil {
fmt.Println("回显服务器发送的数据dial.Read出错了", err)
return
}
fmt.Println("客户端读到服务器的回显数据", string(buf[:read]))
}
}
UDP实现并发-服务器:
由于UDP是“无连接”的,所以,服务器端不需要额外创建监听套接字,只需要指定好IP和port,然后监听该地址,等待客户端与之建立连接,即可通信。
创建监听地址:
func ResolveUDPAddr(network, address string) (*UDPAddr, error)
创建监听连接:
func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error)
接收udp数据:
func (c *UDPConn) ReadFromUDP(b []byte) (int, *UDPAddr, error)
写出数据到udp:
func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error)
演示:
package main
import (
"fmt"
"net"
)
func main() {
ServerAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8000")
if err != nil {
fmt.Println("net.ResolveUDPAddr err:", err)
return
}
fmt.Println("服务器启动成功!")
udpConnect, err := net.ListenUDP("udp", ServerAddr)
if err != nil {
fmt.Println("net.ListenUDP err:", err)
return
}
defer udpConnect.Close()
fmt.Println("服务器创建Socket成功!")
buf := make([]byte, 4096)
count := 0
for {
udpBytes, ConnectAddr, err := udpConnect.ReadFromUDP(buf)
if err != nil {
fmt.Println("udpConnect.ReadFromUDP err:", err)
return
}
count++
fmt.Printf("服务器读到第%v条数据 %v :%s\n", count, ConnectAddr, string(buf[:udpBytes]))
go func() {
udpConnect.WriteToUDP([]byte("回写数据到客户端\n"), ConnectAddr)
}()
}
}
UDP实现并发-客户端:
package main
import (
"fmt"
"net"
"time"
)
func main() {
dial, err := net.Dial("udp", "127.0.0.1:8000")
if err != nil {
fmt.Println("net.Dial出错:", err)
return
}
defer dial.Close()
for {
dial.Write([]byte("我是客户端"))
buf := make([]byte, 4096)
read, err := dial.Read(buf)
if err != nil {
fmt.Println("accept.Read出错:", err)
return
}
fmt.Println("客户端获取到:", string(buf[:read]))
time.Sleep(time.Second)
}
}
|