这篇博客我们来写一个socket小程序,模拟一个简单的聊天程序
server端:
// stydy project main.go
package main
import (
"fmt"
"log"
"net"
"time"
)
func startServer() {
listener, err := net.Listen("tcp", "127.0.0.1:12031")
defer listener.Close()
if err != nil {
fmt.Println(err)
}
for {
conn, err := listener.Accept() //监听客户端发过来的请求, conn是一个和客户端连接的通道
if err != nil { //连接中断
fmt.Println(err)
continue
}
receiveAndSendMsg(conn)
time.Sleep(1 * time.Second)
}
}
func receiveAndSendMsg(conn net.Conn) {
defer conn.Close()
log.Println(conn.RemoteAddr().String())
buffer := make([]byte, 50)
for {
conn.Write([]byte("hi client, i am server:" + time.Now().Format("15:04:05")))
_, err := conn.Read(buffer)
if err != nil {
return
}
log.Printf("msg is : %v\n", string(buffer))
time.Sleep(1 * time.Second)
}
}
func main() {
startServer()
}
Accept()方法监听客户端请求,没有请求时,程序一直等待,直到有客户端连接。
客户端代码:
// client project main.go
package main
import (
"fmt"
"net"
"os"
"time"
)
func startClient() {
conn, err := net.Dial("tcp", "127.0.0.1:12031")
defer conn.Close()
if err != nil {
fmt.Println(err)
}
receiveAndSendMsg(conn)
}
func receiveAndSendMsg(conn net.Conn) {
for {
buffer := make([]byte, 50)
_, err := conn.Read(buffer)
if err != nil {
os.Exit(-1)
}
fmt.Println(string(buffer))
str := "你好,server, 我是客户端:" + time.Now().Format("15:04:05")
conn.Write([]byte(str))
time.Sleep(1 * time.Second)
}
}
func main() {
startClient()
}
这个程序里面,我们在看几个小知识点:
1、string转[]byte:用表达式[]byte(string)转化,反之成立
2、时间格式化:上面我们格式化的是时分秒,这个时间只能是15:04:05是不可以写其它的,如果加上年月日的化就是
time.Now().Format("2006-01-02 15:04:05")
这个也是只能写这个时间。
这是一个简单的socket程序,但是这个程序有一个问题,这里只有一个客户端,如果有多个客户端呢,这个时候,程序会先处理第一个链接的客户端,处理结束,才会处理第二个客户端连接,但是这个程序里面我们是死循环,那么它永远不会处理第二个及后面的,这个怎么办呢,在后面我们学习了goroutine和通道后,我们会解决这个问题。