請從github下載配套代碼: https://github.com/shuningzhang/learn_golang
電子書下載地址: https://u19702000.ctfile.com/dir/19702000-33357795-bb2f31/
大家都知道Web服務(wù)是基于HTTP協(xié)議的匀借,而HTTP協(xié)議又是TCP協(xié)議上的應(yīng)用層協(xié)議蹋宦。因此我們在開發(fā)一個Web服務(wù)之前带射,我們先介紹一下如何使用Go語言開發(fā)一個基于TCP的客戶端與服務(wù)端程序(關(guān)于TCP協(xié)議的原理可以參考本號之前的文章《從socket到TCP協(xié)議世落,透徹理解網(wǎng)絡(luò)編程》)李剖。
程序比較簡單略吨,服務(wù)端用于等待客戶端的連接屏富,連接建立成功后驯耻,如果接到客戶端的數(shù)據(jù),則原封不動的返回相同的數(shù)據(jù)崔慧≈客戶端建立與服務(wù)端的連接,連接建立成功后向服務(wù)端發(fā)送字符串?dāng)?shù)據(jù)尊浪,并等待接收服務(wù)端的返回匣屡。
服務(wù)端
前面已經(jīng)介紹,服務(wù)端用于等待客戶端的連接拇涤,連接建立成功后捣作,如果接到客戶端的數(shù)據(jù),則原封不動的返回相同的數(shù)據(jù)鹅士。如下是服務(wù)端的代碼券躁,監(jiān)聽的端口為8080。
package main
import (
"fmt"
"net" //網(wǎng)絡(luò)通信的庫
"os"
)
func main() {
/* 構(gòu)建服務(wù)端的地址掉盅,端口 */
service := ":8080"
tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
checkError(err)
/* 建立對端口的監(jiān)聽 */
listener, err := net.ListenTCP("tcp", tcpAddr)
checkError(err)
for {
fmt.Println("begin accept")
/* 等待客戶端的連接 */
conn, err := listener.Accept()
if err != nil {
continue
}
buf := make([]byte,1024)
/* 讀取客戶端發(fā)送的數(shù)據(jù)也拜,并打印 */
result, err := conn.Read(buf)
fmt.Println(result, string(buf))
/* 將數(shù)據(jù)原封返回給客戶端 */
conn.Write(buf)
conn.Close()
}
}
func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr,
"Fatal error: %s", err.Error())
os.Exit(1)
}
}
客戶端
客戶端建立與服務(wù)端的連接,連接建立成功后向服務(wù)端發(fā)送字符串?dāng)?shù)據(jù)趾痘,并等待接收服務(wù)端的返回慢哈。客戶端收到服務(wù)端的數(shù)據(jù)后會在終端打印出來永票。
package main
import (
"fmt"
"io/ioutil"
"net"
"os"
)
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr,
"Usage: %s host:port ", os.Args[0])
os.Exit(1)
}
/* 這里解析從命令行輸入的參數(shù)卵贱,包括地址和端口 */
service := os.Args[1]
tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
checkError(err)
/* 建立與服務(wù)端的連接 */
conn, err := net.DialTCP("tcp", nil, tcpAddr)
checkError(err)
/* 向服務(wù)端發(fā)送數(shù)據(jù) */
_, err = conn.Write([]byte("Hello World!\r\n"))
checkError(err)
/* 接收服務(wù)端發(fā)送的數(shù)據(jù),并在終端打印 */
result, err := ioutil.ReadAll(conn)
checkError(err)
fmt.Println(string(result))
os.Exit(0)
}
func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr,
"Fatal error: %s", err.Error())
os.Exit(1)
}
}
測試驗證
測試驗證也比較簡單侣集,首先需要注意觀察一下服務(wù)端的ip地址键俱,然后在服務(wù)端啟動服務(wù)端的程序。假設(shè)服務(wù)端的地址為192.168.142.128世分,此時在客戶端的中斷輸入如下命令:
./client 192.168.142.128:8080
此時可以看到有Hello World编振!字符串輸出。說明整個通信過程是正確的臭埋。如果會用Wireshark或者tcpdump等網(wǎng)絡(luò)監(jiān)測工具踪央,可以看一下整個交互過程。