TCP
socket server
package main
import (
"fmt"
"net"
)
func main() {
// 一. 创建套接字socket
// 指定server端使用的通信协议, 并绑定ip 和 port
listener, err := net.Listen("tcp", "127.0.0.1:8384")
if err != nil{
fmt.Println("server start err :", err)
return
}
fmt.Println("server start success...")
// 二. 创建用于连接和通信的socket
// 调用 Accept 监听连接,此时会阻塞server端,直到有客户端发送连接,, server端每收到一个连接,都会创建一个conn
conn, err:= listener.Accept() // 等待连接
if err != nil{
fmt.Println("server accept err :", err)
return
}
// 三. 向client收发数据
// 1.读取客户端发送的数据
// 创建用于保存收到的数据大小的切片
buf := make([]byte, 4096)
n, err := conn.Read(buf) // 返回的是所收到数据的字节数
if err != nil{
fmt.Println("server read err :", err)
return
}
// 处理收到的数据后,如打印
fmt.Println("server 收到数据:", string(buf[:n])) // 将收到的数据,按照收到的字节数从头切到 n,即:读多少打印多少
// 2.向client发送数据
_, err = conn.Write([]byte("Im ok!"))
if err != nil{
fmt.Println("server write err :", err)
return
}
// 四. 关闭socker , 包括监听socket 和 通信socket
defer listener.Close()
defer conn.Close()
}
socket client
package main
import (
"fmt"
"net"
)
func main() {
// 一. 客户端创建用于通信的socket
// 指定通信协议,并指定server端 IP PORT
conn, err := net.Dial("tcp", "127.0.0.1:8384")
if err != nil{
fmt.Println("client start err :", err)
return
}
// 二. 收发server端数据
// 1.主动向server端发送数据
msg := "Are you ok?"
_, err = conn.Write([]byte(msg))
if err != nil{
fmt.Println("client write err :", err)
return
}
// 2.接收server端的数据
buf := make([]byte, 4096)
n, err := conn.Read(buf)
if err != nil{
fmt.Println("client read err :", err)
return
}
fmt.Println("client 收到数据:", string(buf[:n]))
// 三. 关闭socker
defer conn.Close()
}
?并发版server
package main
import (
"fmt"
"net"
"strings"
)
func HandlerConnent(conn net.Conn) {
defer conn.Close() // 注意完成数据通信后关闭conn
// server可以做一些事情,如处理数据
addr := conn.RemoteAddr() // 获取client addr
fmt.Println(addr.Network()) // 获取socket协议 : tcp
fmt.Println(addr.String()) // 获取client IP PORT : 127.0.0.1:54331
// 三. 循环读取客户端发送的数据
// 创建用于保存收到的数据大小的切片
buf := make([]byte, 4096)
for{
n, err := conn.Read(buf) // 返回的是所收到数据的字节数
// server 与 client 之间的 Read, Write 类似channel的读写端,
// 当写端主动关闭后,读端可以继续读数据,但读到的是0, 所以可以通过是否为0来判断client是否关闭连接
if n == 0{
fmt.Println("client stop..., 断开连接")
return
}
if "exit\n" == string(buf[:n]) || "exit\r\n" == string(buf[:n]){
fmt.Println("client stop..., 断开连接")
return
}
if err != nil{
fmt.Println("server read err :", err) // 注意: 当客户端关闭后,n 等于 0 , err 等于 EOF
return
}
msg := string(buf[:n]) // 将收到的数据,按照收到的字节数从头切到 n,即:读多少打印多少
fmt.Println("server 收到数据:", msg)
// 将客户端发送的数据转大写并返回给client端
_, err = conn.Write([]byte(strings.ToUpper(msg)))
if err != nil{
fmt.Println("server write err :", err)
return
}
}
}
func main() {
// 一. 创建套接字socket
// 指定server端使用的通信协议, 并绑定ip 和 port
listener, err := net.Listen("tcp", "127.0.0.1:8384")
defer listener.Close()
if err != nil{
fmt.Println("server start err :", err)
return
}
fmt.Println("server start success...")
// 二. 创建用于连接通信的socket
// 调用 Accept 监听连接,此时会阻塞server端,直到有客户端发送连接,, server端每收到一个连接,都会创建一个conn
for { // 循环等待创建连接,实现可以接收多个client的连接功能
conn, err:= listener.Accept() // 阻塞等待连接
if err != nil{
fmt.Println("server accept err :", err)
return
}
// 并发创建用于完成server 与 client 数据通信的函数
go HandlerConnent(conn) // 将conn socket传入
}
}
并发版client
package main
import (
"fmt"
"net"
"os"
)
func main() {
// 一. 客户端创建用于通信的socket
// 指定通信协议,并指定server端 IP PORT
conn, err := net.Dial("tcp", "127.0.0.1:8384")
if err != nil{
fmt.Println("client start err :", err)
return
}
// 创建go程, 用来获取键盘输入
go func() {
str := make([]byte, 4096)
for{
n, err := os.Stdin.Read(str) // 获取键盘输入
if err != nil{
fmt.Println("client os.Stdin.Read err :", err)
continue
}
_, err = conn.Write(str[:n])
if err != nil{
fmt.Println("client write err :", err)
return
}
}
}()
// 打印server 返回的数据
buf := make([]byte, 4096)
for{
n, err := conn.Read(buf)
if err != nil{
fmt.Println("client read err :", n, err) // 当server断开与client的连接后 client read err : 0 EOF
return
}
fmt.Println("client 收到数据:", string(buf[:n]))
}
}
|