从零开始学golang之TCP

freedbg · · 982 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

```go 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

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

982 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传