当前位置:网站首页>Golang -- TCP implements concurrency (server and client)
Golang -- TCP implements concurrency (server and client)
2022-07-06 04:55:00 【Java mage】
Server End common function 、 Interface :
Listen function :
func Listen(network, address string) (Listener, error)
network: Optional Protocol :TCP、UDP, Such as :“tcp” or “udp”
address:IP Address + Port number , Such as :“127.0.0.1:8000” or “:8000”
Listener Interface :
type Listener interface {
Accept() (Conn, error)
Close() error
Addr() Addr
}
Conn Interface :
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- Server implementation :
func main() {
// Specify the communication protocol of the server 、ip、 port ,Listen Do not monitor by itself , This step is to create a for listening Socket
listen, err := net.Listen("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("net.Listen error :", err)
return
}
defer listen.Close()
fmt.Println(" The server is up , Wait for the client to connect ")
// Block listening for client connection requests , After the connection is successfully established, the... For communication will be returned Socket
accept, err := listen.Accept()
if err != nil {
fmt.Println("listen.Accept error :", err)
return
}
defer accept.Close()
fmt.Println(" The connection between the server and the client was successful ")
// Read the request initiated by the client
buf := make([]byte, 4096)
read, err := accept.Read(buf)
if err != nil {
fmt.Println("accept.Read error :", err)
return
}
// Process data after receiving data
fmt.Println(" Server get to :", string(buf[:read]))
}
Mac Can pass netcat To test :
TCP- Client implementation :
Server side :
func main() {
// Specify the communication protocol of the server 、ip、 port ,Listen Do not monitor by itself , This step is to create a for listening Socket
listen, err := net.Listen("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("net.Listen error :", err)
return
}
defer listen.Close()
fmt.Println(" The server is up , Wait for the client to connect ")
// Block listening for client connection requests , After the connection is successfully established, the... For communication will be returned Socket
accept, err := listen.Accept()
if err != nil {
fmt.Println("listen.Accept error :", err)
return
}
defer accept.Close()
fmt.Println(" The connection between the server and the client was successful ")
// Read the request initiated by the client
buf := make([]byte, 4096)
read, err := accept.Read(buf)
if err != nil {
fmt.Println("accept.Read error :", err)
return
}
accept.Write(buf[:read]) // Read the data and write it back
// Process data after receiving data
fmt.Println(" Server get to :", string(buf[:read]))
}
client :
func main() {
// Specify the communication protocol of the client 、ip、 port ,Listen Do not monitor by itself , This step is to create a for listening Socket
dial, err := net.Dial("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("net.Dial error :", err)
return
}
defer dial.Close()
// send data
dial.Write([]byte(" I'm the client "))
// Receive the data returned by the server
buf := make([]byte, 4096)
read, err := dial.Read(buf)
if err != nil {
fmt.Println("accept.Read error :", err)
return
}
// Process data after receiving data
fmt.Println(" The client gets :", string(buf[:read]))
}
TCP Implement concurrency - The server :
The above is the client communication of the stand-alone version , If you want to achieve concurrency , Need to use Goroutine+ Cycle to achieve
- Loop read data sent by client
- If the client forcibly closes the connection, it needs to be handled
- The client sends exit when
demonstration :
package main
import (
"fmt"
"net"
"strings"
)
func main() {
// Create a listening socket
listen, err := net.Listen("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("net.Listen error :", err)
return
}
defer listen.Close()
// Create client connection request
fmt.Println(" Server started successfully , Wait for the client to connect !")
for {
accept, err := listen.Accept()
if err != nil {
fmt.Println("listen.Accept error :", err)
return
}
// Call the function that the server communicates with the client
go HandlerConnect(accept)
}
}
func HandlerConnect(accept net.Conn) {
defer accept.Close()
// Get the data sent by the client
// Get the network address of the connected client
addr := accept.RemoteAddr()
fmt.Println(addr, " Client connection successful !")
buf := make([]byte, 4096)
for {
read, err := accept.Read(buf)
if err != nil {
fmt.Println("accept.Read error :", err)
return
}
fmt.Println(" The server reads data :", string(buf[:read]))
// After the simulation server receives the data , Send back to the client , Small to capital
data := strings.ToUpper(string(buf[:read]))
accept.Write([]byte(data))
}
}
TCP Implement concurrency - client :
demonstration :
package main
import (
"fmt"
"net"
"os"
)
func main() {
// Send connection request actively
dial, err := net.Dial("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("et.Dial Something went wrong ", err)
return
}
defer dial.Close()
// os.Stdin(): Get user keyboard entry ,
go func() {
str := make([]byte, 4096)
for {
read, err := os.Stdin.Read(str)
if err != nil {
fmt.Println("os.Stdin.Read Something went wrong ", err)
continue
}
// The read data is written to the server , Read as much as you write
dial.Write(str[:read])
}
}()
buf := make([]byte, 4096)
// Echo the data sent by the server , Capitalize
for {
read, err := dial.Read(buf)
// read=0 Description of the opposite end close connection , If you close the connection, there is no need to read data down here
if read == 0 {
fmt.Println(" It is detected that the server has been disconnected !")
return
}
if err != nil {
fmt.Println(" Echo the data sent by the server dial.Read Something went wrong ", err)
return
}
fmt.Println(" The client reads the echo data of the server ", string(buf[:read]))
}
}
边栏推荐
- 二叉树基本知识和例题
- Nestjs配置文件上传, 配置中间件以及管道的使用
- C'est un petit résumé de l'étude.
- Collection + interview questions
- [buuctf.reverse] 159_[watevrCTF 2019]Watshell
- Dynamic programming (tree DP)
- 麦斯克电子IPO被终止:曾拟募资8亿 河南资产是股东
- Yyds dry goods inventory OSI & tcp/ip
- Building intelligent gray-scale data system from 0 to 1: Taking vivo game center as an example
- Bill Gates posted his 18-year-old resume and expected an annual salary of $12000 48 years ago
猜你喜欢
Introduction of several RS485 isolated communication schemes
Sqlserver query results are not displayed in tabular form. How to modify them
Pagoda configuration mongodb
RT thread analysis log system RT_ Kprintf analysis
Postman管理测试用例
Crazy God said redis notes
Visio draw fan
Flink kakfa data read and write to Hudi
Basic knowledge and examples of binary tree
Codeforces Round #804 (Div. 2)
随机推荐
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
Driver development - hellowdm driver
L'introduction en bourse de MSK Electronics a pris fin: 800 millions de RMB d'actifs de Henan étaient des actionnaires
RTP GB28181 文件测试工具
【Try to Hack】john哈希破解工具
项目经理,你会画原型嘛?项目经理需要做产品设计了?
Bill Gates posted his 18-year-old resume and expected an annual salary of $12000 48 years ago
[lgr-109] Luogu may race II & windy round 6
Platformio create libopencm3 + FreeRTOS project
Idea one key guide package
Postman断言
Postman Association
11. Intranet penetration and automatic refresh
Flody的应用
Unity screen coordinates ugui coordinates world coordinates conversion between three coordinate systems
Selection of slow motion function
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
On the solution of es8316's audio burst
Weng Kai C language third week 3.1 punch in
Platformio create libopencm3 + FreeRTOS project