内容简介:一、用到的net方法1 、客户端:2、服务器
一、用到的net方法
1 、客户端:
var buf [512]byte tcpAddr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:9090") //向服务器拨号 conn, _ := net.DialTCP("tcp", nil, tcpAddr) //获取远程服务器地址 rAddr := conn.RemoteAddr() //发送数据 n, _ := conn.Write([]byte("")) //接收数据 n, _ = conn.Read(buf[0:])
2、服务器
func ResolveTCPAddr(network, address string) (*TCPAddr, error) ResolveTCPAddr返回TCP端点的地址。 网络必须是TCP网络名。 如果地址参数中的主机不是字面IP地址或者端口不是字面端口号,那么ResolveTCPAddr将地址解析为TCP端点的地址。 否则,它将地址解析为一对文字IP地址和端口号。 address参数可以使用主机名,但不建议这样做,因为它将最多返回一个主机名的IP地址。 有关网络和地址的描述,请参阅func Dial参数。 network : Tcp Tcp4 Tcp6 address : :9090 应该是访问地址 返回值:*TCPAddr 地址 第二个返回值:err 监听:func ListenTCP(network string, laddr *TCPAddr) (*TCPListener, error) ListenTCP在本地TCP地址laddr上声明并返回一个*TCPListener,net参数必须是"tcp"、"tcp4"、"tcp6",如果laddr的端口字段为0,函数将选择一个当前可用的端口,可以用Listener的Addr方法获得该端口 第一个参数:TCP 第二个参数 *TCPAddr 地址 返回值 :
具体代码实现
net.go
package main import ( "fmt" "log" "net" "os" ) func main() { tcpAddr, _ := net.ResolveTCPAddr("tcp", ":9090") //向服务器拨号 conn, _ := net.DialTCP("tcp", nil, tcpAddr) go HandlerMessage(conn) //接受来自服务器的消息 buf := make([]byte, 1024) for { length, err := conn.Read(buf) fmt.Println(length) if err != nil { log.Printf("recv server msg failed :%v\n", err) conn.Close() os.Exit(0) break } fmt.Println(string(buf[0:length])) } } func HandlerMessage(conn net.Conn) { //获取用户的地址 username := conn.LocalAddr().String() for { var input string //获取用户发送的消息 fmt.Scanln(&input) if len(input) > 0 { msg := username + " say " + input // _, err := conn.Write([]byte(msg)) if err != nil { conn.Close() break } } } }
server.go
package main import ( "fmt" "net" "os" ) func main() { port := "9090" StartServer(port) } func StartServer(p string) { port := ":" + p //返回tcp地址 tcpAddr, err := net.ResolveTCPAddr("tcp", port) fmt.Println(tcpAddr) if err != nil { os.Exit(0) return } //监听tcp地址 listener, err := net.ListenTCP("tcp", tcpAddr) if err != nil { os.Exit(0) return } buf := make([]byte, 1024) conns := make(map[string]net.Conn) //用户池 messages := make(chan string, 10) //消息的通道 go BroadCastMessage(conns, messages) // //每有一个客户进来就将其放入用户池 for { conn, err := listener.AcceptTCP() if err != nil { fmt.Println("Accept failed") continue } conns[conn.RemoteAddr().String()] = conn //将新进来的用户放进用户池 go HandlerMessage(conn, buf, conns, messages) //开一个协程监听用户是否发送消息 } } //将收到的信息发送到每一个客户端 func BroadCastMessage(cns map[string]net.Conn, messages chan string) { for { messtr := <-messages //接受通道里的消息 //将接收到的消息发送给用户池里的每一个用户 for k, v := range cns { _, err := v.Write([]byte(messtr)) //发送消息 if err != nil { delete(cns, k) //如果出现错误 删除用户 结束本次循环 v.Close() continue } } } } //接受用户发送的消息 func HandlerMessage(conn net.Conn, buf []byte, cns map[string]net.Conn, messages chan string) { for { length, err := conn.Read(buf) if err != nil { conn.Close() delete(cns, conn.RemoteAddr().String()) break } messages <- string(buf[0:length]) //将用户的信息放到通道里 // fmt.Println(string(buf[0:length])) } }
OK!
以上所述就是小编给大家介绍的《golang实现qq聊天之客户端与服务器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 支付宝客户端架构解析:iOS 客户端启动性能优化初探
- 自己动手做数据库客户端: BashSQL开源数据库客户端
- 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
- 客户端HTTP缓存
- 简析移动客户端安全
- 配置Hadoop集群客户端
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JavaScript忍者秘籍
John Resig、Bear Bibeault / 徐涛 / 人民邮电出版社 / 2015-10 / 69.00
JavaScript语言非常重要,相关的技术图书也很多,但没有任何一本书对JavaScript语言的重要部分(函数、闭包和原型)进行深入、全面的介绍,也没有任何一本书讲述跨浏览器代码的编写。本书是jQuery库创始人编写的一本深入剖析JavaScript语言的书。 本书共分四个部分,从准入训练、见习训练、忍者训练和火影训练四个层次讲述了逐步成为JavaScript高手的全过程。全书从高级We......一起来看看 《JavaScript忍者秘籍》 这本书的介绍吧!