golang实现tcp编程主要用到net包下面的几个方法:
net.Listen:监听一个地址
Listener接口中的Accept:接收一个请求连接
net.Dial:和服务端建立连接
package main
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"net"
"os"
"time"
)
var host = flag.String("host", "", "host")
var port = flag.String("port", "9999", "port")
type Msg struct {
Data string `json:"data"`
Type int `json:"type"`
}
type Resp struct {
Data string `json:"data"`
Status int `json:"status"`
}
func main() {
flag.Parse()
var l net.Listener
var err error
l, err = net.Listen("tcp", *host+":"+*port)
if err != nil {
fmt.Println("listen error:", err)
os.Exit(1)
}
defer l.Close()
fmt.Println("listening on " + *host + ":" + *port)
for {
conn, err := l.Accept()
if err != nil {
fmt.Println("accept error:", err)
os.Exit(1)
}
fmt.Printf("message %s->%s\n", conn.RemoteAddr(), conn.LocalAddr())
go handleRequest(conn)
}
}
func handleRequest(conn net.Conn) {
ip := conn.RemoteAddr().String()
defer func() {
fmt.Println("disconnect:" + ip)
conn.Close()
}()
reader := bufio.NewReader(conn)
writer := bufio.NewWriter(conn)
for {
b, _, err := reader.ReadLine()
if err != nil {
return
}
var msg Msg
json.Unmarshal(b, &msg)
fmt.Println("GET==>data ", msg.Data, " type:", msg.Type)
resp := Resp{
Data: time.Now().String(),
Status: 200,
}
r, _ := json.Marshal(resp)
writer.Write(r)
writer.Write([]byte("\n"))
writer.Flush()
}
fmt.Println("done!")
}
package main
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"net"
"os"
"strconv"
"sync"
)
var host = flag.String("host", "localhost", "host")
var port = flag.String("port", "9999", "port")
type Msg struct {
Data string `json:"data"`
Type int `json:"type"`
}
type Resp struct {
Data string `json:"data"`
Status int `json:"status"`
}
func main() {
flag.Parse()
conn, err := net.Dial("tcp", *host+":"+*port)
if err != nil {
fmt.Println("connect error", err)
os.Exit(1)
}
defer conn.Close()
fmt.Println("connecting to " + *host + ":" + *port)
var wg sync.WaitGroup
wg.Add(2)
go handleWrite(conn, &wg)
go handleRead(conn, &wg)
wg.Wait()
}
func handleWrite(conn net.Conn, wg *sync.WaitGroup) {
defer wg.Done()
for i := 10; i > 0; i-- {
d := "hello" + strconv.Itoa(i)
msg := Msg{
Data: d,
Type: 1,
}
b, _ := json.Marshal(msg)
writer := bufio.NewWriter(conn)
writer.Write(b)
writer.Write([]byte("\n"))
writer.Flush()
}
fmt.Println("write done")
}
func handleRead(conn net.Conn, wg *sync.WaitGroup) {
defer wg.Done()
reader := bufio.NewReader(conn)
for i := 1; i <= 10; i++ {
line, _, err := reader.ReadLine()
if err != nil {
fmt.Println("read error", err)
return
}
var resp Resp
json.Unmarshal(line, &resp)
fmt.Println("status", resp.Status, " content:", resp.Data)
}
fmt.Println("read done")
}