tcp client server in go

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010643777/article/details/81432760

 A simple example of tcp client and server in golang, most of its code is copied from blogs[1][2].
tcpclient.go

package main
import (
    "flag"
    "fmt"
    "net"
    "os"
    "strings"
    "time"
)
var(
    sendData [1024]byte
)

var host = flag.String("host", "localhost", "host")
var port = flag.String("port", "3333", "port")
func GetMilliSeconds() int64{
    now := time.Now()
    nanos := now.UnixNano()
    millis := nanos / 1000000
    return millis
}
func main() {
    flag.Parse()
    conn, err := net.Dial("tcp", *host+":"+*port)
    if err != nil {
        fmt.Println("Error connecting:", err)
        os.Exit(1)
    }
    for i:=0;i<len(sendData);i++{
        sendData[i]=uint8(i)
    }
    defer conn.Close()
    fmt.Println("Connecting to " + *host + ":" + *port)
    done := make(chan string)
    total:=10*1024; //10M
    go handleWrite(conn, done,total)
    go handleRead(conn, done)
    start:=GetMilliSeconds()
    Loop:
    for{
    select{
        case sigstr:=<-done:
        if strings.Compare(sigstr,"Sent")==0{
            elapse:=GetMilliSeconds()-start;
            fmt.Printf("send time %d\n",elapse)
        }else if strings.Compare(sigstr,"Read")==0{
            feedback:=GetMilliSeconds()-start;
            fmt.Printf("ack time %d\n",feedback)
            break Loop;
        }
    }
    }
}
func handleWrite(conn net.Conn, done chan string,total int) {

    for i := total; i > 0; i-- {
        var bar []byte = sendData[:]
        _, e := conn.Write(bar)
        if e != nil {
            fmt.Println("Error to send message because of ", e.Error())
            break
        }
    }
    done <- "Sent"
}
func handleRead(conn net.Conn, done chan string) {
    buf := make([]byte, 1024)
    reqLen, err := conn.Read(buf)
    if err != nil {
        fmt.Println("Error to read message because of ", err)
        return
    }
    fmt.Println(string(buf[:reqLen]))
    done <- "Read"
}

tcpserver.go

package main
import(
    "net"
    "flag"
    "fmt"
)
var(
    total=10*1024*1024
)
var host = flag.String("host", "localhost", "host")
var port = flag.String("port", "3333", "port")
func main() {
  flag.Parse()
  fmt.Printf("listen on %s\n",*port)
  newConns := make(chan net.Conn, 128)
  deadConns := make(chan net.Conn, 128)
  publishes := make(chan []byte, 128)
  conns := make(map[net.Conn]bool)
    listener, err := net.Listen("tcp", *host+":"+*port)
    if err != nil { panic(err) }
    go func() {
        for {
            conn, err := listener.Accept()
            if err != nil { panic(err) }
            newConns <- conn
        }
    }()
    for {
        select {
        case conn := <-newConns:
            conns[conn] = true
            go func() {
                buf := make([]byte, 1024)
                hasread:=0
                for {
                    nbyte, err := conn.Read(buf)
                    if err != nil {
                        deadConns <- conn
                        break
                    } else {
                        hasread+=nbyte
                        if(hasread>=total){
                            conn.Write([]byte("hello ok"))
                            deadConns <- conn
                            break;
                        }
                        //fragment := make([]byte, nbyte)
                        //copy(fragment, buf[:nbyte])
                        //publishes <- fragment
                    }
                }
            }()
        case deadConn := <-deadConns:
            _ = deadConn.Close()
            delete(conns, deadConn)
        case publish := <-publishes:
            for conn, _ := range conns {
                go func(conn net.Conn) {
                    totalWritten := 0
                    for totalWritten < len(publish) {
                        writtenThisCall, err := conn.Write(publish[totalWritten:])
                        if err != nil {
                            deadConns <- conn
                            break
                        }
                        totalWritten += writtenThisCall
                    }
                }(conn)
            }
        }
    }
    listener.Close()
}

[1]How to write a TCP chat server in 55 lines of Golang
[2]Golang实现简单tcp服务器04 – 服务器的粘包处理
[3]Golang convert type [N]byte to []byte

猜你喜欢

转载自blog.csdn.net/u010643777/article/details/81432760