版权声明:本文为博主原创文章,未经博主允许不得转载。 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