奇妙的go语言(聊天室的开发)

奇妙的go语言(聊天室的开发)

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。


【 声明:版权全部,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】


    这是一篇关于聊天室开发的博客,原来文章的地址来自于。这篇文章非常具有代表性,对于代码中的函数部分内容,不想多说什么,仅仅是对它的实现进行一些必要的解说。关于代码,大家既能够在这里阅读,也能够跳转到那篇博客,继续阅读。


package main

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

////////////////////////////////////////////////////////
//
//错误检查
//
////////////////////////////////////////////////////////
func checkError(err error,info string) (res bool) {
	
	if(err != nil){
		fmt.Println(info+"  " + err.Error())
		return false
	}
	return true
}

////////////////////////////////////////////////////////
//
//server端接收数据线程
//參数:
//		数据连接 conn
//		通讯通道 messages
//
////////////////////////////////////////////////////////
func Handler(conn net.Conn,messages chan string){
	
	fmt.Println("connection is connected from ...",conn.RemoteAddr().String())
	
	buf := make([]byte,1024)
	for{
		lenght, err := conn.Read(buf)
		if(checkError(err,"Connection")==false){
			conn.Close()
			break
		}
		if lenght > 0{
			buf[lenght]=0
		}
		//fmt.Println("Rec[",conn.RemoteAddr().String(),"] Say :" ,string(buf[0:lenght]))
		reciveStr :=string(buf[0:lenght])
		messages <- reciveStr
			
	}
		
}

////////////////////////////////////////////////////////
//
//server发送数据的线程
//
//參数
//		连接字典 conns
//		数据通道 messages
//
////////////////////////////////////////////////////////
func echoHandler(conns *map[string]net.Conn,messages chan string){
	
	
	for{
		msg:= <- messages
		fmt.Println(msg)
		
		for key,value := range *conns {
			
			fmt.Println("connection is connected from ...",key)
			_,err :=value.Write([]byte(msg))
			if(err != nil){
				fmt.Println(err.Error())
				delete(*conns,key)
			}
			
		}
	}
	
}


////////////////////////////////////////////////////////
//
//启动server
//參数
//	端口 port
//
////////////////////////////////////////////////////////
func StartServer(port string){
		service:=":"+port //strconv.Itoa(port);
		tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
		checkError(err,"ResolveTCPAddr")
		l,err := net.ListenTCP("tcp",tcpAddr)
		checkError(err,"ListenTCP")
		conns:=make(map[string]net.Conn)
		messages := make(chan string,10)
		
		//启动server广播线程
		go echoHandler(&conns,messages)
		
		for  {
			fmt.Println("Listening ...")
			conn,err := l.Accept()
			checkError(err,"Accept")
			fmt.Println("Accepting ...")
			conns[conn.RemoteAddr().String()]=conn
			//启动一个新线程
			go Handler(conn,messages) 
			
		}
		
}


////////////////////////////////////////////////////////
//
//client发送线程
//參数
//		发送连接 conn
//
////////////////////////////////////////////////////////
func chatSend(conn net.Conn){
	
	var input string
	username := conn.LocalAddr().String()
	for {
		
		fmt.Scanln(&input)
		if input == "/quit"{
			fmt.Println("ByeBye..")
			conn.Close()
			os.Exit(0);
		}
		
		
		lens,err :=conn.Write([]byte(username + " Say :::" + input))
		fmt.Println(lens)
		if(err != nil){
			fmt.Println(err.Error())
			conn.Close()
			break
		}
		
	}
	
}

////////////////////////////////////////////////////////
//
//client启动函数
//參数
//		远程ip地址和端口 tcpaddr
//
////////////////////////////////////////////////////////
func StartClient(tcpaddr string){
	
	tcpAddr, err := net.ResolveTCPAddr("tcp4", tcpaddr)
	checkError(err,"ResolveTCPAddr")
	conn, err := net.DialTCP("tcp", nil, tcpAddr)
	checkError(err,"DialTCP")
	//启动client发送线程
	go chatSend(conn)	
	
	//開始client轮训
	buf := make([]byte,1024)
	for{
		
		lenght, err := conn.Read(buf)
		if(checkError(err,"Connection")==false){
			conn.Close()
			fmt.Println("Server is dead ...ByeBye")
			os.Exit(0)
		}
		fmt.Println(string(buf[0:lenght]))
		
	}
}


////////////////////////////////////////////////////////
//
//主程序
//
//參数说明:
//	启动server端:  Chat server [port]				eg: Chat server 9090
//	启动client:    Chat client [Server Ip Addr]:[Server Port]  	eg: Chat client 192.168.0.74:9090
//
////////////////////////////////////////////////////////
func main(){
	
	
	if len(os.Args)!=3  {	
		fmt.Println("Wrong pare")
		os.Exit(0)
	}
	
	if os.Args[1]=="server" && len(os.Args)==3 {
		
		StartServer(os.Args[2])
	}
	
	
	if os.Args[1]=="client" && len(os.Args)==3 {
		
		StartClient(os.Args[2])
	}
	
	
}

     主要知识点例如以下:


    (1)代码中包含了server和client的内容,假设是server,直接输入./chat server 9090就可以,client也非常easy,输入./chat client :9090就好;


    (2)假设是client,事实上就包含了两部分内容,一部分是chatSend函数,接受用户的输入;还有一部分是connect到server,接受相关信息;


    (3)假设是server,略微复杂一点,有三个部分组成。第一部分就是不停地accept各个client;第二个就是为每个client创立Handler函数,接受client发来的信息;第三个就是echoHandler函数,它的作用就是将从某一用户接受过来的信息广播给其它全部的client,就是这么简单。





版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/118722.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • linux内存不足导致tomcat宕机

    linux内存不足导致tomcat宕机情况,正常运行的服务器,突然tomcat不能访问了因为服务器的内存是2g的,所以就怀疑是内存不够了,所导致开始排查ps-ef|greptomcat[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TTLyQ5EC-1585835537446)(E:\Workspaces\Markdown\linux\记一次内存不够的情况.assets\image-…

  • Q学习和深度Q学习(DQN)论文笔记「建议收藏」

    Q学习和深度Q学习(DQN)论文笔记「建议收藏」Q学习(Q-learning)强化学习中有个很重要的递归关系,贝尔曼方程(BellmanEquation):Qπ(st,at)=E[r+γE[Qπ(st+1,at+1)]]Q^\pi(s_t,a_t)=E[r+\gammaE[Q^\pi(s_{t+1},a_{t+1})]]Qπ(st​,at​)=E[r+γE[Qπ(st+1​,at+1​)]]这个公式实际上也揭露了状态的马尔科夫性质,也…

  • EmguCV 常用函数功能说明「建议收藏」

    AbsDiff,计算两个数组之间的绝对差。dst(I)c=abs(src1(I)c-src2(I)c)。所有数组必须具有相同的数据类型和相同的大小(或ROI大小)。累加,将整个图像或其所选区域添加到累加器和。累积产品,将2张图像或其选定区域的产品添加到累加器中。AccumulateSquare,将输入src或其选定的区域,增加到功率2,添加到累加器sqsum。累积权重,计算输

  • LoadRunner 11 安装及激活成功教程

    LoadRunner 11 安装及激活成功教程注意事项:  安装前,把所有的杀毒软件和防火墙关闭。  若以前安装过LoadRunner,则将其卸载。  安装路径不要带中文字符。  如果系统为WIN7,旗舰版才能安装。  安装完毕,需激活成功教程

  • lunix针对用户的常用操作命令

    lunix针对用户的常用操作命令(1)使用who查看目前有哪些用户登录了服务器,见下图[root@vm18~]#whorootpts/02015-03-2710:23(192.168.9.188)从上文可以看出用户root使用ip地址为192.168.9.188登录到linux系统上 (2)看看root都在什么时间登录过系统 [root@vm18~]#lastrootrootpts/0192.168.9.1…

  • leetcode第三题_九八K

    leetcode第三题_九八K有 n 根长度互不相同的木棍,长度为从 1 到 n 的整数。请你将这些木棍排成一排,并满足从左侧 可以看到 恰好 k 根木棍。从左侧 可以看到 木棍的前提是这个木棍的 左侧 不存在比它 更长的 木棍。例如,如果木棍排列为 [1,3,2,5,4] ,那么从左侧可以看到的就是长度分别为 1、3 、5 的木棍。给你 n 和 k ,返回符合题目要求的排列 数目 。由于答案可能很大,请返回对 109 + 7 取余 的结果。示例 1:输入:n = 3, k = 2输出:3解释:[1,3,2], [2,3,

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号