Go语言实现简单的聊天程序

简单的TCP多客户端聊天

服务器每收到一个连接,就让一个goroutine去通过sock和客户端进行交流。goroutine执行流程,先接受信息,在发送信息。
客户端从终端获取输入,发送给指定IP和端口的服务器,接受服务器的信息。
虽然可以实现多客户端通信,但是两个客户端有两个终端,服务器只有一个终端。由标准输入获取的信息发送给服务器端上一次接受信息的客户端(服务端上一次接受完客户端信息之后的goroutine阻塞在从标准输入获取信息那里了)
在这里插入图片描述
服务器

package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
)

func log(msg string, err error) {
	fmt.Println(msg, err)
	os.Exit(-1)
}

func work(sock net.Conn) {
	for {
		var buf [1024]byte
		n, err := sock.Read(buf[:])
		if err != nil {
			log("读数据出错:", err)
		}
		fmt.Printf("%v说:%v", sock.RemoteAddr().String(), string(buf[:n]))

		var str string
		reader := bufio.NewReader(os.Stdin)
		str, err = reader.ReadString('\n')
		if err != nil {
			fmt.Println("发送失败:", err)
			os.Exit(-1)
		}
		sock.Write([]byte(str))
	}
}

func main() {
	listenSock, err := net.Listen("tcp", "127.0.0.1:8000")
	if err != nil {
		log("监听失败:", err)
	}
	for {
		connectSock, err := listenSock.Accept()
		defer connectSock.Close()
		if err != nil {
			log("接受请求失败:", err)
		}
		go work(connectSock)
	}
}

客户端

package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
)

func main() {
	server, err := net.Dial("tcp", "127.0.0.1:8000")
	if err != nil {
		fmt.Println("拨号失败:", err)
		os.Exit(-1)
	}
	defer server.Close()
	for {
		var str string
		var buf [1024]byte //字节数组
		reader := bufio.NewReader(os.Stdin)
		str, err = reader.ReadString('\n')
		if err != nil {
			fmt.Println("发送失败:", err)
			os.Exit(-1)
		}
		server.Write([]byte(str))
		var n int
		n, err = server.Read(buf[:])
		if err != nil {
			fmt.Println("读取失败:", err)
			os.Exit(-1)
		}
		fmt.Printf("%v说:%v", server.RemoteAddr().String(), string(buf[:n]))
	}
}

简单的UDP多客户端聊天

在这里插入图片描述
UDP服务器无连接,接受到消息,讲消息输出,在回复“收到”字样。
服务器处于死循环中,任何客户端只要客户端拨号的IP和端口是UDP服务器的IP和端口,该udp服务器都可以接受,也不需要额外goroutine来处理多个客户端的消息。

服务器

package main

import (
	"fmt"
	"net"
	"os"
)

func main() {
	conn, err := net.ListenUDP("udp", &net.UDPAddr{
		IP:   net.ParseIP("127.0.0.1"),
		Port: 9999,
	})
	if err != nil {
		fmt.Println("ListenUDP erro:", err)
		os.Exit(-1)
	}
	defer conn.Close()
	for {
		var buf [1024]byte
		n, addr, err := conn.ReadFromUDP(buf[:])
		if err != nil {
			fmt.Println("接受消息出错:", err)
		}
		fmt.Println(addr.String(), string(buf[:n]))
		conn.WriteToUDP([]byte("收到"), addr)
	}
}

客户端

package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
)

func main() {
	con, err := net.DialUDP("udp", nil, &net.UDPAddr{
		IP:   net.ParseIP("127.0.0.1"),
		Port: 9999,
	})
	if err != nil {
		fmt.Println("拨号失败:", err)
	}
	for {
		reader := bufio.NewReader(os.Stdin)
		str, _ := reader.ReadString('\n')
		str = strings.Trim(str, "\r\n") //去掉换行符,好和Q比较
		if strings.ToUpper(str) == "Q" {
			fmt.Println("退出聊天系统")
			return //退出
		}
		con.Write([]byte(str))

		var buf [1024]byte
		n, _, _ := con.ReadFromUDP(buf[:])
		fmt.Println(con.RemoteAddr().String(), string(buf[:n]))
	}
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值