Go語言網(wǎng)絡(luò)編程、TCP(海量用戶即時(shí)通訊系統(tǒng))
Go語言網(wǎng)絡(luò)編程、TCP
網(wǎng)絡(luò)編程有兩種:
①TCP socket編程,是網(wǎng)絡(luò)編程的主流。底層是基于Tcp/ip 協(xié)議的。如: QQ聊天
②B/S結(jié)構(gòu)的http編程,http底層依舊是用tcp socket實(shí)現(xiàn)的如:京東商城
?
TCP/IP(Transmission Control Protocol/Internet Protocol)
傳輸控制協(xié)議/因特網(wǎng)互聯(lián)協(xié)議,又叫網(wǎng)絡(luò)通訊協(xié)議。
是Internet最基本的協(xié)議、Internet國(guó)際互聯(lián)網(wǎng)絡(luò)的基礎(chǔ),由網(wǎng)絡(luò)層的IP協(xié)議和傳輸層的TCP協(xié)議組成的。
OSI與TCP/IP參考模型 (推薦TCP/IP協(xié)議3卷)


IP地址
每個(gè)internet上的主機(jī)和路由器都有一個(gè)ip地址,它包括網(wǎng)絡(luò)號(hào)和主機(jī)號(hào),ip 地址有ipv4(32位)、ipv6(128 位)。
可以通過ipconfig來查看。
?
端口(port)
TCP/IP 協(xié)議中的端口,是邏輯意義上的端口。
如果把IP地址比作一間房子,端口就是出入這間房子的門。
一個(gè)IP地址的端口可以有65536(256×256)個(gè),端口是通過端口號(hào)來標(biāo)記的,整數(shù),范圍是從0到65535(256×256-1)
分類:
0:保留端口;
1~1024:固定端口,又叫有名端口,即被某些程序固定使用,一般程序員不使用。
22: SSH 遠(yuǎn)程登錄協(xié)議 ??23: telnet使用 ? 21: ftp 使用
25: smtp 服務(wù)使用 ??80: iis 使用 ?7: echo 服務(wù)
1025~65535 :動(dòng)態(tài)端口,程序員可使用。
使用注意:
①在計(jì)算機(jī)(尤其是做服務(wù)器)要盡可能的少開端口
②一個(gè)端口只能被一個(gè)程序監(jiān)聽
③使用 netstat–an,可查看本機(jī)有哪些端口在監(jiān)聽
④使用 netstat–anb ,可查看監(jiān)聽端口的pid,在結(jié)合任務(wù)管理器關(guān)閉不安全的端口
?
bufio包實(shí)現(xiàn)了有緩沖的I/O。
net包提供了可移植的網(wǎng)絡(luò)I/O接口,包括TCP/IP、UDP、域名解析和Unix域socket。
大部分只需要Dial、Listen和Accept函數(shù)提供的基本接口;以及相關(guān)的Conn和Listener接口。
?
Dial函數(shù)和服務(wù)端建立連接:
conn, err := net.Dial("tcp", "google.com:80")
status, err := bufio.NewReader(conn).ReadString('\n')
?
Listen函數(shù)創(chuàng)建的服務(wù)端:
ln, err := net.Listen("tcp", ":8080")
if err != nil {…}
for {
conn, err := ln.Accept()
if err != nil {
// handle error
continue
}
go handleConnection(conn)
}
tcp socket編程的客戶端和服務(wù)器端
Golang socket編程中客戶端和服務(wù)器的網(wǎng)絡(luò)分布
?

tcp socket編程的快速入門
服務(wù)端的處理流程:
①監(jiān)聽端口8888
②接收客戶端的tcp鏈接,建立客戶端和服務(wù)器端的鏈接
③創(chuàng)建goroutine,處理該鏈接的請(qǐng)求(通??蛻舳藭?huì)通過鏈接發(fā)送請(qǐng)求包)
客戶端的處理流程:
①建立與服務(wù)端的鏈接
②發(fā)送請(qǐng)求數(shù)據(jù)【終端】,接收服務(wù)器端返回的結(jié)果數(shù)據(jù)
③關(guān)閉鏈接

代碼的實(shí)現(xiàn):以下是用到的函數(shù):
func (c *TCPConn) RemoteAddr() Addr:emoteAddr返回遠(yuǎn)端網(wǎng)絡(luò)地址
?
type Listener interface {
Addr() Addr ? ?// Addr返回該接口的網(wǎng)絡(luò)地址
Accept() (c Conn, err error) ?// Accept等待并返回下一個(gè)連接到該接口的連接
Close() error ? ?// Close關(guān)閉該接口,并使任何阻塞的Accept操作都會(huì)不再阻塞并返回錯(cuò)誤。
}
Listener是一個(gè)用于面向流的網(wǎng)絡(luò)協(xié)議的公用的網(wǎng)絡(luò)監(jiān)聽器接口。多個(gè)線程可能會(huì)同時(shí)調(diào)用一個(gè)Listener方法。
?
func (b *Reader) ReadString(delim byte) (line string, err error)
ReadString讀取直到第一次遇到delim字節(jié),返回一個(gè)包含已讀取的數(shù)據(jù)和delim字節(jié)的字符串。
如果在讀取到delim之前遇到了錯(cuò)誤,它會(huì)返回在錯(cuò)誤之前讀取的數(shù)據(jù)以及該錯(cuò)誤(一般是io.EOF)。
當(dāng)且僅當(dāng)ReadString方法返回的切片不以delim結(jié)尾時(shí),會(huì)返回一個(gè)非nil的錯(cuò)誤。
?
服務(wù)器端功能:

?

客戶端功能:

?海量用戶即時(shí)通訊系統(tǒng):
項(xiàng)目要保存用戶信息和消息數(shù)據(jù),需要學(xué)習(xí)數(shù)據(jù)庫(Redis或Mysql) 。如何在Golang中使用Redis。
完成用戶登錄:
先完成指定用戶的驗(yàn)證,這里先說明一個(gè)Message的組成,并發(fā)送一個(gè)Message的流程。
?

思路分析:
①讓客戶端發(fā)送消息本身。
②服務(wù)器端接受到消息, 然后反序列化成對(duì)應(yīng)的消息結(jié)構(gòu)體。
③服務(wù)器端根據(jù)反序列化成對(duì)應(yīng)的消息, 判斷是否登錄用戶是合法,返回LoginResMes。
④客戶端解析返回的 LoginResMes,顯示對(duì)應(yīng)界面。
這里需要做函數(shù)的封裝
?


在Redis手動(dòng)添加測(cè)試用戶,并畫圖+說明注意。
完成登錄時(shí)能返回當(dāng)前在線用戶:

完成登錄用可以群聊:



?
?
?
?