Golang基于TCP/IP的简单聊天程序

lucifd · · 10356 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Server.go

package main

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

func main() {
	addr, err := net.ResolveTCPAddr("tcp", ":4040")
	checkErr(err)
	listen, err := net.ListenTCP("tcp", addr)
	checkErr(err)
	fmt.Println("Start server...")
	for {
		conn, err := listen.Accept()
		checkErr(err)
		go Handle(conn)// 每次建立一个连接就放到单独的线程内做处理
	}
}

const BufLength = 128

var users map[string]net.Conn = make(map[string]net.Conn, 10)

func Handle(conn net.Conn) {
	conn.Write([]byte("欢迎加入2B聊天组~"))
	for {
		data := make([]byte, 0)//此处做一个输入缓冲以免数据过长读取到不完整的数据
		buf := make([]byte, BufLength)
		for {
			n, err := conn.Read(buf)
			if err != nil && err != io.EOF {
				checkErr(err)
			}
			data = append(data, buf[:n]...)
			if n != BufLength {
				break
			}
		}

		cmd := strings.Split(string(data), "|")
		fmt.Println("命令:", cmd)

		switch cmd[0] {
		case "nick":
			fmt.Println("注册名称:" + cmd[1])
			users[cmd[1]] = conn
		case "say":
			for k, v := range users {
				if k != cmd[1] {
					fmt.Println("给" + k + "发送消息:" + cmd[2])
					v.Write([]byte(cmd[1] + ":[" + cmd[2] + "]"))
				}
			}
		}
	}
}

func checkErr(err error) {
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

Client.go

package main

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

var nick string = ""

func main() {
	addr, err := net.ResolveTCPAddr("tcp", ":4040")
	checkErr(err)
	conn, err := net.DialTCP("tcp", nil, addr)
	checkErr(err)
	// 读取提示
	data := make([]byte, 1024)
	conn.Read(data)
	fmt.Println(string(data))
	// 输入昵称
	fmt.Print("输入昵称:")
	fmt.Scanf("%v", &nick)
	fmt.Println("Hello " + nick)
	conn.Write([]byte("nick|" + nick))

	go Handle(conn)

	for {
		someTex := ""
		fmt.Scanf("%v", &someTex)
		conn.Write([]byte("say|" + nick + "|" + someTex))
	}
}

const BufLength = 128

func Handle(conn net.Conn) {
	for {
		data := make([]byte, 1024)
		buf := make([]byte, BufLength)
		for {
			n, err := conn.Read(buf)
			if err != nil && err != io.EOF {
				checkErr(err)
			}
			data = append(data, buf[:n]...)
			if n != BufLength {
				break
			}
		}

		fmt.Println(string(data))
	}
}

func checkErr(err error) {
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:lucifd

查看原文:Golang基于TCP/IP的简单聊天程序

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

10356 次点击  
加入收藏 微博
3 回复  |  直到 2000-01-01 00:00:00
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传