精品国产一区在线_av无码中文字幕无码王_天海翼三点刺激高潮不停_好硬好大好爽视频_欧美高清一区三区在线专区_香蕉黄色片

微軟公司宣布不再支持你正在使用的 IE瀏覽器,這會嚴重影響瀏覽網(wǎng)頁,請使用微軟最新的Edge瀏覽器
廠商專區(qū)
產(chǎn)品/技術(shù)
應用分類

AWorks編程——socket通信

2019-07-25 14:37 來源:致遠電子 編輯:電源網(wǎng)

一、概述

要編寫通過計算機網(wǎng)絡通信的程序,首先要確定這些程序相互通信使用的協(xié)議,通常使用TCP或UDP協(xié)議族。TCP是面向連接的傳輸協(xié)議,建立連接時需要經(jīng)過三次握手,斷開連接時需要經(jīng)過四次握手,中間傳輸數(shù)據(jù)也要回復ACK包進行確認。而UDP是非連接的傳輸協(xié)議,沒有建立連接和斷開連接的過程,它只是簡單的把數(shù)據(jù)丟到網(wǎng)絡中,也不明確區(qū)分服務器和客戶端。因此TCP比UDP協(xié)議更加可靠,且TCP和UDP編程大致相同,所以本文就以TCP協(xié)議為例,建立圖 1所示的基本客戶/服務器網(wǎng)絡模型,進行通信。

AWorks編程——socket通信

圖 1 基本服務器-客戶端模型

二、基本套接字編程

圖 2給出了一對客戶與服務器進程之間發(fā)生的典型事件的時間表。服務器首先啟動,稍后客戶端啟動連接到服務器。所有的客戶和服務器都從調(diào)用socket開始,它返回套接字描述符;客戶隨后調(diào)用connect,服務器則調(diào)用bind、listen和accept;建立連接之后調(diào)用send、recv函數(shù)進行數(shù)據(jù)傳輸。數(shù)據(jù)傳輸完成后,套接字使用標準的closesocket函數(shù)關(guān)閉。

AWorks編程——socket通信

圖 2 基本客戶/服務器程序的套接字函數(shù)

● socket()函數(shù):指定期望的通信協(xié)議類型(使用IPv4的TCP、使用IPv6的UDP等)創(chuàng)建套接字。

● blind()函數(shù):將套接字與本地的IP地址和端口綁定。

● connect()函數(shù):客戶端向服務器發(fā)出連接請求。

● listen()函數(shù):僅服務器調(diào)用,使套接字進入被動監(jiān)聽狀態(tài)。所謂被動監(jiān)聽是指當沒有客戶端請求時,套接字處于“睡眠”狀態(tài),只有當接收到客戶端請求時,套接字才會被喚醒來響應請求。

● accept()函數(shù):當套接字處于監(jiān)聽狀態(tài)時,可以通過aceept函數(shù)來接收客戶端的請求。

● send/recv()函數(shù):發(fā)送和接收函數(shù)。

● closesocket()函數(shù):關(guān)閉套接字,回收資源。

三、網(wǎng)絡連接與配置

socket通信程序基于網(wǎng)絡之上,常規(guī)的開發(fā)板一般都攜帶以太網(wǎng)外設(shè),所以本文以以太網(wǎng)為例,配置開發(fā)板的網(wǎng)絡連接。

首先需要用網(wǎng)線連接開發(fā)板的網(wǎng)口和電腦,來建立網(wǎng)絡的物理連接。其次在aworks sdk包中的aw_prj_params.h文件中打開以太網(wǎng)設(shè)備宏,如程序清單 1。

#define AW_DEV_IMX1050_ENET             /**< \brief iMX1050 ENET (有線網(wǎng)卡) */

程序清單 1 打開以太網(wǎng)配置宏

再次在awbl_hwconf_imx1050_enet.h文件中配置以太網(wǎng)的IP地址、子網(wǎng)掩碼和網(wǎng)關(guān),并關(guān)閉dhcp,使用靜態(tài)的IP地址,如程序清單 2。

aw_local char *__get_ipaddr (void)

{

   return "192.168.1.10";

}


aw_local char *__get_netmsk (void)

{

   return "255.255.255.0";

}


aw_local char *__get_gateway (void)

{

   return "192.168.1.1";

}


. . . .


aw_local bool_t __get_dhcp_en (void)

{

return FALSE;

}

程序清單 2 IP地址設(shè)置

最后修改電腦為靜態(tài)IP地址并與開發(fā)板IP地址位于同一網(wǎng)段。

四、TCP客戶端實例

按照基本的套接字編程流程,建立一個客戶端,我們只需要調(diào)用socket、connect、send、recv、closesocket函數(shù)即可,如程序清單 3,首先使用socket創(chuàng)建一個TCP類型的套接字,再調(diào)用connect連接到已指定的服務器(IP地址為192.168.1.34、端口號為4000),當服務器端接收客戶端的連接請求后,connect函數(shù)退出阻塞狀態(tài),進入循環(huán),再在循環(huán)中調(diào)用send函數(shù)向服務器發(fā)送數(shù)據(jù),調(diào)用recv函數(shù)(阻塞)接收數(shù)據(jù)。當數(shù)據(jù)傳輸完成后,使用closesocket關(guān)閉連接,回收資源。

程序清單 3 回聲客戶端程序

#include "aworks.h"

#include "aw_delay.h"

#include "aw_task.h"

#include "net/aw_net.h"

#include "net/aw_sockets.h"

#include


/* 客戶端訪問的服務器IP地址 */

#define REMOTE_SERVER_ADDR          "192.168.1.34"      /* 對應服務器的 IP 地址,用戶需要根據(jù)具體創(chuàng)建的服務端的IP地址修改 */

#define REMOTE_SERVER_PORT          4000                  /* 客戶端訪問服務器端口 */


/**

* \brief net 示例程序入口

* \return 無

*/

void demo_tcp_client_entry (void)

{

   struct sockaddr_in server_addr;

   int rcv_len;

   int sock;

   char net_buf[1500];

   memset(net_buf,'\0',1500);


   /* 設(shè)置客戶端訪問的服務器IP地址、端口號 */

   inet_aton(REMOTE_SERVER_ADDR, &server_addr.sin_addr);

   server_addr.sin_family = AF_INET;

   server_addr.sin_port = htons(REMOTE_SERVER_PORT);

   server_addr.sin_len = sizeof(server_addr);


   aw_kprintf("TCP client: connecting...\r\n");

   while(1) {


       sock = socket(AF_INET, SOCK_STREAM, 0);/* 創(chuàng)建socket套接字 */

       if (sock < 0) {

           aw_kprintf("TCP server socket failed!\r\n");

           return;

       }


       /* 連接服務器  */

       if (0 == connect(sock, (struct sockaddr *) &server_addr, sizeof(server_addr))) {

           aw_kprintf("TCP client: connected.\r\n");

           while(1) {

               send(sock, "hello,i'm tcp client.", 21, 0); /* 向服務器發(fā)送數(shù)據(jù) */

               rcv_len = recv(sock, net_buf, sizeof(net_buf), 0);/* 接收服務器發(fā)送的數(shù)據(jù) */

               if (rcv_len <= 0) {

                   aw_kprintf("TCP client: disconnect. ret=%d, err=%d\r\n", rcv_len, errno);

                   break;

               }

               aw_kprintf("recv:%s\r\n",net_buf);/*打印數(shù)據(jù)*/

               memset(net_buf,'\0',1500);/*清空緩存區(qū)*/

           }

       }


       closesocket(sock); /* 關(guān)閉此連接 */

       aw_mdelay(1000);

   }

}

程序編寫完成后,我們使用TCP上位機軟件測試。打開TCP調(diào)試軟件,如圖 3。創(chuàng)建服務器,如圖 4。最后啟動服務器,如圖 5。

AWorks編程——socket通信

圖 3 TCP調(diào)試工具

AWorks編程——socket通信

圖 4 創(chuàng)建服務器

AWorks編程——socket通信

圖 5 啟動服務器

以上步驟就緒后,在主程序中調(diào)用demo_tcp_client_entry()入口函數(shù),編譯、下載程序到開發(fā)板,待程序運行之后,可以在shell界面看到TCP客戶端連接成功,如圖 6,此時在上位機軟件上可以看到建立的TCP連接,在發(fā)送區(qū)域向客戶端發(fā)送數(shù)據(jù),在接收區(qū)將看到客戶端回發(fā)的數(shù)據(jù),如圖 7。shell界面打印客戶端收到的數(shù)據(jù),如圖 8。

AWorks編程——socket通信

圖 6 TCP客戶端連接成功

7

圖 7 服務器數(shù)據(jù)顯示

AWorks編程——socket通信

圖 8 客戶端數(shù)據(jù)打印

五、TCP服務器實例

按照基本的套接字編程流程,建立服務器,我們只需要調(diào)用socket、bind、listen、accept、send、recv、closesocket函數(shù)即可,如程序清單 4,首先使用socket函數(shù)創(chuàng)建TCP類型的套接字,然后調(diào)用bind函數(shù)綁定本地網(wǎng)卡的IP地址和端口號,使用listen監(jiān)聽客戶端的請求,然后accept函數(shù)將阻塞等待客戶端的請求連接,當服務器監(jiān)聽到有客戶端請求連接時,accept退出阻塞狀態(tài),建立連接,進入循環(huán),使用send、recv收發(fā)數(shù)據(jù)。當數(shù)據(jù)傳輸完成后,使用closesocket關(guān)閉連接,回收資源。

程序清單 4 非阻塞服務器

#include "aworks.h"

#include "aw_delay.h"

#include "aw_task.h"


#include "net/aw_net.h"

#include "net/aw_sockets.h"


#include


#define LOCAL_SERVER_PORT           4000                  /* 本地服務器端口 */


/* 客戶端訪問的服務器IP地址 */


/**

* \brief net 示例程序入口

* \return 無

*/

void demo_tcp_server_block_entry (void)

{

   struct sockaddr_in server_addr, client_addr;

   int server_sock, client_sock;

   int rcv_len;

   char net_buf[1500];

   socklen_t len;


   memset(net_buf,'\0',1500);

   memset(&server_addr, 0, sizeof(server_addr));

   memset(&client_addr, 0, sizeof(client_addr));


   /*創(chuàng)建socket套接字,使用TCP連接 */

   server_sock = socket(AF_INET, SOCK_STREAM, 0);

   if (0 > server_sock) {

       AW_INFOF(("TCP server socket failed!" ENDL));

       return;

   }


   /*設(shè)置服務器的端口等屬性*/

   server_addr.sin_family = AF_INET;

   server_addr.sin_port = htons(LOCAL_SERVER_PORT); /* 設(shè)置服務器的端口 */

   server_addr.sin_addr.s_addr = 0; /* 在所有接口上監(jiān)聽 */

   server_addr.sin_len = sizeof(server_addr);

   memset(&(server_addr.sin_zero), 8, sizeof(server_addr.sin_zero));


   /* 綁定本地接口  */

   if (bind(server_sock, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {

       AW_INFOF(("TCP server bind failed!" ENDL));

       closesocket(server_sock);

       return;

   }


   /* 進入監(jiān)聽模式 */

   listen(server_sock, 1);

   AW_INFOF(("TCP server: listen on %s:%d" ENDL,

           inet_ntoa(server_addr.sin_addr), htons(server_addr.sin_port)));


   len = sizeof(struct sockaddr);


   for (;;) {

       /* 阻塞等待客戶端連接 */

       client_sock = accept(server_sock, (struct sockaddr *) &client_addr, &len);

       if (client_sock > 0) {

           AW_INFOF(("TCP server: client %s:%d connected." ENDL,

                   inet_ntoa(client_addr.sin_addr), htons(client_addr.sin_port)));


           for (;;) {

                   send(client_sock, "hello,i'm tcp server.", 21, 0);/*發(fā)送數(shù)據(jù)*/

                   rcv_len = recv(client_sock, &net_buf, sizeof(net_buf), 0);/* 接收數(shù)據(jù),阻塞,直到收到數(shù)據(jù) */

                   if (rcv_len <= 0) {

                       break;

                   }

                   aw_kprintf("recv:%s\r\n",net_buf);/*打印接收得到的數(shù)據(jù)*/

                   memset(net_buf,'\0',1500);/*清空緩存區(qū)*/

           }


           closesocket(client_sock); /* 關(guān)閉此連接 */

           AW_INFOF(("TCP server: client %s:%d leave." ENDL,

                   inet_ntoa(client_addr.sin_addr), htons(client_addr.sin_port)));


           aw_mdelay(5);


       }

   }

}

程序編寫完成后,將服務器例程入口函數(shù)demo_tcp_server_block_entry()放入主函數(shù)中編譯、下載到開發(fā)板,程序運行后在shell界面可看到服務器已經(jīng)啟動,如圖 9。

AWorks編程——socket通信

圖 9 服務器啟動

服務器啟動后,同樣使用TCP上位機軟件建立客戶端進行測試,指定服務器的IP和端口號,如圖 10。

10

圖 10 創(chuàng)建客戶端

客戶端創(chuàng)建后,點擊連接,如圖 11。

AWorks編程——socket通信

圖 11 連接到服務器

連接成功后,在發(fā)送區(qū)發(fā)送數(shù)據(jù),接收區(qū)可以看到服務器回發(fā)的數(shù)據(jù),如圖 12所示。此時在串口界面也可以看到服務器收到的數(shù)據(jù),如圖 13。

AWorks編程——socket通信

圖 12 客戶端收發(fā)數(shù)據(jù)

AWorks編程——socket通信

圖 13 服務器收到的數(shù)據(jù)

六、出錯調(diào)試

如果程序運行后,沒有成功建立連接,可按照以下步驟查看網(wǎng)絡狀態(tài):

首先在串口界面調(diào)用 AWorks的Shell命令ip addr,查看以太網(wǎng)IP地址是否配置成功,如圖 14。然后使用ping命令測試網(wǎng)絡通信是否正常,如圖 15。

AWorks編程——socket通信

圖 14 查看ip地址

AWorks編程——socket通信

圖 15 測試網(wǎng)絡是否正常

聲明:本內(nèi)容為作者獨立觀點,不代表電源網(wǎng)。本網(wǎng)站原創(chuàng)內(nèi)容,如需轉(zhuǎn)載,請注明出處;本網(wǎng)站轉(zhuǎn)載的內(nèi)容(文章、圖片、視頻)等資料版權(quán)歸原作者所有。如我們采用了您不宜公開的文章或圖片,未能及時和您確認,避免給雙方造成不必要的經(jīng)濟損失,請電郵聯(lián)系我們,以便迅速采取適當處理措施;歡迎投稿,郵箱∶editor@netbroad.com。

微信關(guān)注
技術(shù)專題 更多>>
技術(shù)專題之EMC
技術(shù)專題之PCB

頭條推薦

電子行業(yè)原創(chuàng)技術(shù)內(nèi)容推薦
客服熱線
服務時間:周一至周五9:00-18:00
微信關(guān)注
獲取一手干貨分享
免費技術(shù)研討會
editor@netbroad.com
400-003-2006
主站蜘蛛池模板: 丰满美女冒白浆久久久久久久 | 久久99国产视频 | 少妇被粗大的猛烈进出va视频 | 中国xxxxxx片免费播放 | 国产下药迷晕一区二区三区在线看 | 欧美日韩精品一区二区三区在线观看 | 男人J进入女人J内部免费网站 | 91免费影片在线观看 | 午夜在线视频一区二区三区 | 久久久久久久免费视频 | 欧美整片在线 | 狠狠躁日日躁 | 亚洲AV无码国产精品久久 | 亚洲国产成人无码影片在线播放 | 亚洲Aⅴ无码专区在线观看春色 | 久久人人爽人人人人爽AV | 国产在线永久视频 | 亚洲av日韩精品久久久久 | 中文字幕58页 | 久久久久久久久久久国产 | 午夜免费无码福利视频 | 五月婷婷在线视频观看 | 噜噜噜躁狠狠躁狠狠精品视频 | 日本无人区码suv | 精品成人免费一区二区不卡 | 操无毛逼 | aa国产| 扒开jk美女狂揉动漫 | 国产精品福利片 | 涩涩网站免费 | 男男黄色软件 | 97国内揄拍国内精品对白 | 自拍亚洲一区 | 国产一级毛片在线 | 国产精品美女黄网 | 成人激情五月天 | tianlula在线观看网址 | 快看视频在线免费看 | 理论片在线国产精品 | 色鬼成人免费网站视频 | 中文无码天天AV天天爽 |