從零開始學golang之TCP
package main
import (
"flag"
"fmt"
"net"
"os"
"time"
)
/**
* tcp 啟動 連結 三次握手 關閉四次
* 慢啟動 + 擁塞視窗
* 門限控制 < 擁塞視窗 進入擁塞避免
* 在傳送資料後 檢測 ack 確認超時 或者 收到重複ack 確認 操作門限值 和 擁塞視窗值 來限流
* 接收方 使用通告視窗 告知傳送可接受多少位元組
*
* 傳送方:滑動視窗協議
*/
//結構體內嵌介面
type Man struct {
iTest
name string
}
type iTest interface {
hello()
}
type Em struct {
good string
}
func (em *Em) hello() {
fmt.Println(em.good)
}
func (man *Man) hello() {
fmt.Println(man.name)
}
var workerChan = make(chan *net.TCPConn, 10000)
var graddr *string
func main() {
// vman := Man{
// &Em{
// good: "goodman",
// },
// "helloman"}
// vman.hello()
// fmt.Println(vman)
nf := flag.String("name", "server", "input server or client")
graddr = flag.String("ip", "127.0.0.1:999", "ip:port")
flag.Parse()
fmt.Println(*nf)
if *nf == "server" {
server()
} else {
client()
}
var wait string
fmt.Scanln(&wait)
}
func server() {
laddr, aerr := net.ResolveTCPAddr("tcp", ":999")
if aerr != nil {
os.Exit(1)
}
listen, lerr := net.ListenTCP("tcp", laddr)
defer listen.Close()
if lerr != nil {
os.Exit(2)
}
//plan2 code start
for i := 0; i < 10; i++ {
go sworker2(workerChan)
}
st := time.Now()
var cn int
cn = 0
//plan2 code end
for {
tcpConn, cerr := listen.AcceptTCP()
if cerr == nil {
cn++
//go sworker(tcpConn) //plan 1
workerChan <- tcpConn //plan 2 減少了工作協程建立
}
if time.Since(st).Seconds() >= 2 {
fmt.Println("accept tcp client :", cn)
cn = 0
st = time.Now()
}
}
}
/**
* 通過chan,的工作執行緒
*/
func sworker2(conns <-chan *net.TCPConn) {
fmt.Println("sworker2")
var b [1500]byte
for conn := range conns {
//for {
_, err := conn.Read(b[0:])
if err == nil {
//fmt.Println(string(b[0:len]))
}
conn.Write([]byte("HELLO WORLD"))
//conn.Close()
//}
}
}
/**
* 工作協程
*/
func sworker(conn *net.TCPConn) {
fmt.Println("sworker")
var b [1500]byte
for {
len, err := conn.Read(b[0:])
if err == nil {
fmt.Println(string(b[0:len]))
}
conn.Write([]byte("HELLO WORLD"))
}
}
func client() {
//linux 預設檔案數開啟1024
//ulimit -n 50000 修改
for i := 0; i < 40000; i++ {
fmt.Println("create clint", i)
go func() {
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
raddr, rerr := net.ResolveTCPAddr("tcp", *graddr)
if rerr != nil {
fmt.Println(rerr)
return
//os.Exit(3)
}
tcpConn, dterr := net.DialTCP("tcp", nil, raddr)
if dterr != nil {
fmt.Println(dterr)
return
}
var b [1500]byte
wlen, err := tcpConn.Write([]byte("ARE-U-THERE"))
if err == nil && wlen > 0 {
tcpConn.Read(b[0:])
//fmt.Println(string(b[0:rlen]))
} else {
fmt.Println(err)
}
}()
}
}
所有程式碼地址:https://github.com/godla/TCP-IP-Study
更多原創文章乾貨分享,請關注公眾號
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- 從零開始學golang之udpGolangUDP
- 從零開始學golang之 PrimGolang
- 從零開始學golang之DijkstraGolang
- 從零開始學golang之gin加上gormGolangORM
- 從零開始學golang之Dynamic programming --LCSGolang
- 從零開始學golang之圖-鄰接矩陣Golang矩陣
- 從零開始學golang之RedBlackTree-DeleteGolangdelete
- 從零開始netty學習筆記之TCP粘包和拆包Netty筆記TCP
- 從零開始學YC-Framework之鑑權Framework
- 從零開始學習C++之遞推C++
- 從零開始學習KafkaKafka
- 從零開始學習機器學習機器學習
- 【ROS】從零開始學ROSROS
- 從零開始學習laravelLaravel
- 從零開始學PythonPython
- 從零開始學 Python 之基礎語法Python
- 從零開始netty學習筆記之BIONetty筆記
- 從零開始netty學習筆記之protobufNetty筆記
- 從零開始學 Spring BootSpring Boot
- eclipse學習從零開始Eclipse
- 從零開始搭建 gRPC 服務 – Golang 篇(一)RPCGolang
- 從零開始搭建 gRPC 服務 - Golang 篇(二)RPCGolang
- 從零開始學習C++之if判斷語句C++
- ORACLE從零開始系列之SQL(一)OracleSQL
- 從零開始學Electron筆記(一)筆記
- 從零開始學Electron筆記(二)筆記
- 從零開始學Electron筆記(七)筆記
- 從零開始學Electron筆記(六)筆記
- 從零開始學Electron筆記(三)筆記
- 從零開始學Electron筆記(四)筆記
- 從零開始學Electron筆記(五)筆記
- 從零開始學習 Go ——安裝Go
- 從零開始學C語言pdfC語言
- 【從零開始學爬蟲】建立模板爬蟲
- 從零開始學mitmproxy抓包工具MIT
- 從零開始學java(五)運算子Java
- 30天從零開始學習SwiftSwift
- 從零開始學五筆(一):概述