上一篇文章实现了的是单次通信,且一个服务器只能连接一个客户端。这里使用goroutine实现并发版的,可以实现多个客户端连接服务器,实现并发请求。示意图如下:
server端代码:
package main
import (
"fmt"
"net"
"strings"
)
func main() {
//指定服务器通信协议、IP地址、Port端口,创建一个用于监听的socket---listener
listener ,err := net.Listen("tcp","127.0.0.1:8000")
if err != nil{
fmt.Println("net.Listener err:",err)
return
}
fmt.Println("服务器已启动...")
defer listener.Close()//关闭socket
//循环监听客户端连接请求
for {
conn ,err := listener.Accept()
if err != nil{
fmt.Println("listener.Accept err:",err)
return
}
go HandleConnect(conn)
}
}
func HandleConnect(conn net.Conn) {
defer conn.Close()
//获取连接客户端的Addr
addr := conn.RemoteAddr()
fmt.Println(addr,"客户端连接成功")
//循环读取客户端发送的数据
buf := make([]byte,4096)
for {
n ,err := conn.Read(buf)
if err != nil{
fmt.Println("conn.Read err:",err)
return
}
if n == 0{
fmt.Println("服务器检测到客户端已关闭,断开连接")
return
}
if "exit\n"==string(buf[:n]){
fmt.Println("服务器收到客户端退出请求,断开连接")
return
}
fmt.Printf("服务器读到%s客户端发来的数据%s:",addr,string(buf[:n]))
//小写转大写,回发给客户端
S := strings.ToUpper(string(buf[:n]))
conn.Write([]byte(S))
}
}
client端代码:
package main
import (
"fmt"
"net"
"os"
)
func main() {
//指定服务器IP+port,创建通信socket--conn
conn,err := net.Dial("tcp","127.0.0.1:8000")
if err != nil{
fmt.Println("net.Dial err:",err)
return
}
defer conn.Close()
//获取用户键盘输入,将数据发送给服务器
go func() {
buf := make([]byte,4096)//将键盘输入存入buf缓冲区
for {
n ,err := os.Stdin.Read(buf)//读取键盘输入
if err != nil{
fmt.Println("os.Stdin.Read err:",err)
continue
}
//将键盘读取的数据发送给服务器
conn.Write(buf[:n])
}
}()
//读服务器回发的大写数据
buffer :=make([]byte,4096)
for {
n,err := conn.Read(buffer)//从conn连接中读取数据,将读取出来的数据存入buffer中
if err != nil{
fmt.Println("conn.Read err:",err)
return
}
fmt.Println("读到服务器回发的数据:",string(buffer[:n]))
}
}
演示:
1.直接在ide中启动服务器:如下图所示:
2.打开两个终端,用于模拟两个客户端。两个终端分别运行客户端的代码并发送数据:
3.此时服务器收到了两个客户端发来的数据: