本章節(jié)使用的資料已經(jīng)放到了開發(fā)板網(wǎng)盤資料中,路徑為:“11_Linux 系統(tǒng)開發(fā)進(jìn)階\77_章節(jié)_網(wǎng)絡(luò)通信-套字節(jié) TCP 使用資料”。 iTOP-IMX6ULL 實現(xiàn)基于 TCP 的 socket 編程。 在 linux 下,網(wǎng)絡(luò)資源非常豐富,底層的東西不需要去管,只需要知道怎么實現(xiàn)最終需要的功能即可。 77.1 實驗操作 TCP 是一種面向連接的、可靠的、基于 IP 的傳輸層協(xié)議。通過 TCP 可以保證傳送的數(shù)據(jù)的正確性。 Linux 下網(wǎng)絡(luò)通信程序基本上都是采用 socket 的方式。socket 起源于 Unix,而 Unix/Linux 基本哲學(xué)之一就是“一切皆文件”,都可以用“打開 open->讀寫 read/write->關(guān)閉 close”模式來操作。Socket 就是該模式的一個實現(xiàn),socket 即是一種特殊的文件,一些 socket 函數(shù)。就是對其進(jìn)行的操作(讀/寫 IO、打開、關(guān)閉)。說白了 socket 是應(yīng)用程序與 TCP/IP 協(xié)議族通信的中間軟件抽象層,它是一組接口。現(xiàn)在看一下基于 TCP/IP 應(yīng)用程序通信的流程,如圖 77.1.1。 ![]() 通過上圖可以看到 TCP/IP 通信是基于服務(wù)器/客戶端的模式來實現(xiàn)的,首先是服務(wù)器(server)端調(diào)用socket 函數(shù)創(chuàng)建一個套接字,然后調(diào)用 bind 綁定函數(shù),綁定函數(shù)主要是設(shè)置通信時使用哪種地址族(IPv4,IPv6 等),使用的端口號。然后調(diào)用 listen 函數(shù)來監(jiān)聽客戶端的連接請求。 現(xiàn)在來看下客戶端(client)端的流程,首先調(diào)用 socket 函數(shù)創(chuàng)建一個套接字,然后調(diào)用 connect 函數(shù)連接服務(wù)器,這時服務(wù)器端的 listen 函數(shù)監(jiān)聽到客戶端的連接請求就會調(diào)用 accept 函數(shù)去接受請求,這樣連接就建立好了。之后雙方就可以調(diào)用 read/write 函數(shù)收發(fā)數(shù)據(jù)了,在完成通信以后服務(wù)器(server)和客 戶端(client)調(diào)用 close 函數(shù)關(guān)閉創(chuàng)建的套接字。 下面來看一個實現(xiàn) TCP/IP 的通信的例子,首先來看一下服務(wù)器(server)端的代碼: ![]() ![]() 程序首先是包含一些需要用到的頭文件,然后是 main 主函數(shù),在 main 函數(shù)里面首先是定義了一些變量,然后調(diào)用 socket 函數(shù)創(chuàng)建一個套接字,socket 函數(shù)的第二個參數(shù)是 SOCK_STREAM,表示創(chuàng)建的是TCP 連接。然后調(diào)用 bzero 函數(shù)把變量 s_add 清零,然后給 s_add 結(jié)構(gòu)里面的變量賦值: ![]() 然后調(diào)用 bind 綁定函數(shù),使用的是 IPv4 協(xié)議族,然后調(diào)用 listen 監(jiān)聽函數(shù),監(jiān)聽用戶的連接請求。在監(jiān)聽到用戶的請求后調(diào)用 accept 函數(shù)接受請求,然后進(jìn)入到循環(huán)發(fā)送的代碼,會循環(huán)發(fā)送“hello,welcometo my server”+發(fā)送次數(shù)號,最后會調(diào)用 close 關(guān)閉套接字。 下面來看看客戶端(client)端的代碼: ![]() ![]() 首先是包含一些需要的頭文件,然后進(jìn)入 main 主函數(shù)定義了一些變量,然后調(diào)用 socket 函數(shù)創(chuàng)建套接字,然后調(diào)用 bzero 函數(shù)把變量 s_add 清零,然后給 s_add 結(jié)構(gòu)里面的變量賦值: ![]() 然后調(diào)用 connect 函數(shù)來連接服務(wù)器(server),在連接成功后,就進(jìn)入了循環(huán)接收函數(shù),使用 read 函數(shù)接收服務(wù)器發(fā)送的數(shù)據(jù)。最后會調(diào)用 close 函數(shù)關(guān)閉套接字。 下面來編譯下這兩個程序,服務(wù)器(server)的程序運行在虛擬機(jī) Ubuntu 上,所以使用下面的命令編譯: gcc -o server server.c 這樣就生成了 server 可執(zhí)行文件,客戶端(client)的程序運行在 iTOP-IMX6UL 開發(fā)板上,使用下面的命令編譯: arm-none-linux-gnueabi-gcc -o client client.c 這樣就生成了 client 可執(zhí)行程序,把 client 下載到 iTOP-IMX6UL 開發(fā)板上,現(xiàn)在開始運行這兩個程序,首先在虛擬機(jī) Ubuntu 上運行 serevr 程序,如圖 77.1.2。 ![]() 可以看到 server 打印出來的運行信息,現(xiàn)在 server 運行到了 listen 函數(shù)開始監(jiān)聽客戶端的連接。下面在 iTOP-IMX6ULL 開發(fā)板上運行 client 程序(因為我把 client 下載到了/bin 目錄下,所以先進(jìn)入到/bin 目錄)執(zhí)行下面的命令: ./client 192.168.1.77 上面命令里面的 192.168.1.77 是虛擬機(jī) Ubuntu 的 IP 地址,看到程序連接成功,首先看一下虛擬機(jī)Ubuntu 上的 server 打出的信息,如圖 77.1.3。 ![]() 可以看到上圖中 server 打印出了客戶端的 ip 地址和端口號“Server start get connectfrom 0xc0a801e6 :0xe171”。 然后看一下 iTOP-IMX6UL 開發(fā)板串口的打印信息,如圖 77.1.4。 ![]() 通過上圖可以看到打印連接成功“connect ok !”,然后串口會一直打印 read ok REC: hello,welcome to my server(0) 至此,基于 TCP/IP 的 socket 網(wǎng)絡(luò)編程就已經(jīng)完成了。 ![]() |