【Go语言】golang简易TCP服务器和客户机实现

今天介绍golang版本的通信基础:基于TCP的客户端和服务器实现,参考书籍:The Way To Go

那时学习java的时候也是做过通信的,当时是socket编程,服务器监听某一个端口,然后客户机去连接,简单的聊天室就实现了。后来有变成多线程的聊天室,可以进行群聊什么的了,后期可以传图片传音乐,加上UI那一块儿,山寨QQ就OK了。现在我来用golang实现一下简易的聊天室,实现了客户机连接服务器,给服务器发消息,服务器接受消息,客户机退出,服务器可以收到退出信息,以及多个客户机同时连入一个服务器。主要的思路和java一样的,服务器监听某一个端口,客户机去连接,然后发送消息就OK了。上代码了。

package main
//服务器端
import (
"fmt"
"log"
"net"  //支持的通信的包,一定要引进
)

//开始服务器
func startServer() {
//连接主机、端口,采用tcp方式通信,监听7777端口
listener, err := net.Listen("tcp", "localhost:7777")
checkError(err)
fmt.Println("建立成功!")
for {
//等待客户端接入
conn, err := listener.Accept()
checkError(err)
//开一个goroutines处理客户端消息,这是golang的特色,实现并发就只go一下就好
go doServerStuff(conn)
}
}

//处理客户端消息
func doServerStuff(conn net.Conn) {
nameInfo := make([]byte, 512)//生成一个缓存数组
_, err := conn.Read(nameInfo)
checkError(err)

for {
buf := make([]byte, 512)
_, err := conn.Read(buf)//读取客户机发的消息
flag := checkError(err)
if flag == 0 {
break
}
fmt.Println(string(buf))//打印出来
}
}

//检查错误
func checkError(err error) int {
if err != nil {
if err.Error() == "EOF" {
//fmt.Println("用户退出了")
return 0
}
log.Fatal("an error!", err.Error())
return -1
}
return 1
}
func main() {
//开启服务
startServer()
}

以上是服务器的实现,具体看代码注释

package main
//客户机
import (
	"bufio"  //便于读写的包bufferio
	"fmt"
	"log"
	"net"
	"os"
	"strings"
)

//连接服务器
func connectServer() {
	//接通
	conn, err := net.Dial("tcp", "localhost:7777")
	checkError(err)
	fmt.Println("连接成功!\n")
	//输入
	inputReader := bufio.NewReader(os.Stdin)
	fmt.Println("你是谁?")
	name, _ := inputReader.ReadString('\n')
	//
	trimName := strings.Trim(name, "\r\n")
	conn.Write([]byte(trimName + " 接入了\n "))
	for {
		fmt.Println("我们来聊天吧!按quit退出")
		//读一行
		input, _ := inputReader.ReadString('\n')
		trimInput := strings.Trim(input, "\r\n")
		//如果quit就退出
		if trimInput == "quit" {
			fmt.Println("再见")
			conn.Write([]byte(trimName + " 退出了 "))
			return
		}
		//写出来
		_, err = conn.Write([]byte(trimName + " says " + trimInput))
	}
}

//检查错误
func checkError(err error) {
	if err != nil {
		log.Fatal("an error!", err.Error())
	}
}

//主函数
func main() {
	//连接servser
	connectServer()
}

以上是客户机代码,具体看注释

运行的时候,分别go run server和client,你变可以看到这样就可以连接成功了。
服务器只用开一个,客户机可以开任意个,并且相互之间没有干扰。

OK,一个简单的多线程聊天室就实现了。后期可以加上更多的功能,但无非就是去处理输入输出,重点都已经有了。

刘凯宁@C2P
20140807

Share