初学go,确实go在网络开发方面提供的很多便捷
- 自动化的编译工具,一个go build搞定一切
- 丰富的标准库,几乎所有的开源组件都支持go了
- 统一的编码风格
虽然在语法上及一些编写格式上还存在一些生疏,但感觉慢慢会喜欢上这个语言,虽然个人追求更底层,但是代码工程就是如此,能复用别人的轮子就不要自己造,这也是go和C++的一大区别吧,C++有时太多需要自己造的轮子,标准化上确实比go差些。
第一次写简单的TCP通讯:
server.go 的代码:
package main
import (
"config"
"fmt"
"net"
"time"
)
func handleConnection(conn net.Conn) {
var data []byte = make([]byte, 5, 10)
defer conn.Close()
conn.SetReadDeadline(time.Now().Add(time.Duration(10) * time.Second)) // 100ms
_, err := conn.Read(data)
if err != nil {
fmt.Println("read data failed, err=" + err.Error())
return
}
str := string(data)
fmt.Println("server recv:" + str)
sendData := []byte(conn.RemoteAddr().String())
conn.Write(sendData)
}
func main() {
fmt.Println("hellow")
config.LoadConfig()
ln, err := net.Listen("tcp", ":8080")
if err != nil {
fmt.Println("listen to 8080 error")
return
}
for {
conn, err := ln.Accept()
if err != nil {
fmt.Println("conn accept failed")
return
}
go handleConnection(conn)
}
}
一开始一直遇到Read函数返回EOF错误,后面查了些资料,才想起来切片需要make初始化。
另外还需要明白,切片初始化长度为5的话,那么最多接收5个字节,其他数据就循环接收这样。
client.go 代码
package main
import (
"fmt"
"io"
"net"
"strconv"
"time"
)
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:8080")
if err != nil {
fmt.Println("dial failed")
}
data := []byte("hello i'm client")
n, errConn := conn.Write(data)
defer conn.Close()
if errConn != nil {
fmt.Println("write failed, err=" + errConn.Error())
return
}
fmt.Println("write succeed, count=" + strconv.Itoa(n))
conn.SetReadDeadline(time.Now().Add(time.Duration(10) * time.Second))
for {
recvData := make([]byte, 100, 1024)
_, err := conn.Read(recvData)
if err != nil {
if err == io.EOF {
break
}
fmt.Println("read failed, err=" + err.Error())
}
fmt.Println("read data:" + string(recvData))
}
fmt.Println("end request")
}
对go的面向对象和面向过程,有时总是感觉混乱,用多了可能就好了吧