學習嵌入式第三十五天

文章目錄

  • 網絡(續上)
    • 1.函數接口
    • 2.相關功能實現
      • 1.TCP連接
      • 2.UDP
  • 習題

網絡(續上)

1.函數接口

  • sendto

    原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
    功能:向一個指定的目標地址發送數據
    參數:sockfd:socket返回的套接字描述符buf:向包含要發送數據的緩沖區的指針len:要發送的數據長度flags:修改套接字調用行為的標志位,通常為0dest_addr:指向一個sockaddr結構體addrlen:指向的結構體的長度
    返回值:成功返回實際發送的字節數失敗返回-1
    
  • recvfrom

    原型:ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
    功能:從套接字接收數據,并捕獲發送數據方的源地址
    參數:sockfd:socket返回的套接字描述符buf:指向用于存放接收數據的緩沖區的指針len:緩沖區的最大長度flags:控制接受操作的標志位,通常為0src_addr:輸出參數,一般為NULL,不為NULL時,函數將發送方的地址信息填充到這個結構體中addrlen:輸入輸出參數輸入時:必須指向一個整數,大小為src_addr緩沖區的大小輸出時:函數會修改這個整數,并將其設置為src_addr中實際存儲的地址信息的真實長度
    返回值:成功返回接收到的字節數失敗返回-1
    

2.相關功能實現

1.TCP連接

  • 客戶端連接

    int tcp_client_connect(char const *ip,char const *port){int fd = socket(AF_INET,SOCK_STREAM,0);//創建一個TCP套接字if(fd < 0){perror("socket fail");return -1;}//創建失敗struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));//初始化服務器地址結構體seraddr.sin_family = AF_INET;seraddr.sin_port = htons(atoi(port));//設置端口號seraddr.sin_addr.s_addr = inet_addr(ip);//輸入自己的IP
    /*嘗試連接到服務器,失敗返回-1,成功返回套接字描述符*/if(connect(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0){perror("connect fail");return -1;}return fd;
    }
    
  • 服務器連接

    int tcp_accept(char const *ip,char const *port){int fd = socket(AF_INET,SOCK_STREAM,0);//創建一個TCP套接字if(fd < 0){perror("socket fail");return -1;}//創建失敗res_fd[0] = fd;printf("fd = %d\n",fd);struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));//初始化服務器地址結構體seraddr.sin_family = AF_INET;seraddr.sin_port = htons(atoi(port));//設置端口seraddr.sin_addr.s_addr = inet_addr(ip);//設置IP
    /*綁定套接字到指定的IP和端口*/if(bind(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0){perror("connect fail");return -1;}
    /*監聽端口,準備接受連接*/if(listen(fd,5) < 0){perror("listen fail");return -1;}
    /*接受一個客戶端的連接,并返回連接的文件描述符*/int connfd = accept(fd,NULL,NULL);if(connfd < 0){perror("accept fail");return -1;}res_fd[1] = connfd;return connfd;
    }
    

2.UDP

  • 客戶端向服務器端發送消息,服務器端回復收到

    • 客戶端

      int main(){// 創建 UDP 套接字int clifd = socket(AF_INET,SOCK_DGRAM,0);if(clifd < 0){perror("socket fail"); // 創建失敗,輸出錯誤信息return -1;}// 定義并初始化服務器地址結構體struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET; // IPv4seraddr.sin_port = htons(50000); // 端口號50000,轉為網絡字節序seraddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服務器IP// 主循環,不斷發送和接收消息while(1){char buf[1024] = {0}; // 發送緩沖區// 從標準輸入讀取一行數據fgets(buf,sizeof(buf),stdin);// 發送數據到服務器,包含字符串結束符int ret = sendto(clifd,buf,strlen(buf)+1,0,(const struct sockaddr*)&seraddr,sizeof(seraddr));char rbuf[1024] = {0}; // 接收緩沖區// 接收服務器返回的數據recvfrom(clifd,rbuf,sizeof(rbuf)+1,0,NULL,NULL);// 打印服務器返回的數據printf("buf = %s\n",rbuf);// 清空接收緩沖區memset(rbuf,0,sizeof(rbuf));}return 0;
      }
      
    • 服務器端

      int main(){// 創建 UDP 套接字int serfd = socket(AF_INET,SOCK_DGRAM,0);if(serfd < 0){perror("socket fail"); // 創建失敗,輸出錯誤信息return -1;}// 定義并初始化服務器地址結構體struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET; // IPv4seraddr.sin_port = htons(50000); // 端口號50000,轉為網絡字節序seraddr.sin_addr.s_addr = INADDR_ANY; // 監聽所有網卡// 綁定套接字和地址if(bind(serfd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0){perror("fail to bind"); // 綁定失敗,輸出錯誤信息return -1;}// 主循環,不斷接收和回復客戶端消息while(1){char buf[1024]; // 接收緩沖區struct sockaddr_in cliaddr; // 客戶端地址結構體socklen_t len = sizeof(cliaddr); // 地址長度// 接收客戶端消息,獲取客戶端地址int ret = recvfrom(serfd,buf,sizeof(buf),0,(struct sockaddr*)&cliaddr,&len);// 打印接收到的字節數printf("ret = %d \n",ret);printf("--------------------------\n");// 打印客戶端IP地址printf("cliaddr = %s\n",inet_ntoa(cliaddr.sin_addr));// 打印客戶端端口號printf("cliport = %d\n",ntohs(cliaddr.sin_port));printf("--------------------------\n");// 構造回復消息char sbuf[1024] = {0};sprintf(sbuf,"recv:%s",buf);// 發送回復消息給客戶端sendto(serfd,sbuf,strlen(sbuf)+1,0,(struct sockaddr*)&cliaddr,sizeof(cliaddr));// 清空發送緩沖區memset(sbuf,0,sizeof(sbuf));}return 0;
      }
      

習題

1.客戶端向服務器端發送一個文件名,服務器將文件內容打包發給客戶端

  • 客戶端

    int main(){int clifd = socket(AF_INET,SOCK_DGRAM,0);if(clifd < 0){perror("socket fail");return -1;}struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");msg_t msg;msg.type = -1;fgets(msg.buf,sizeof(msg.buf),stdin);msg.buf[strlen(msg.buf)-1] = '\0';sendto(clifd,msg.buf,sizeof(msg.buf),0,(const struct sockaddr*)&seraddr,sizeof(seraddr));int fd = open(msg.buf,O_WRONLY|O_TRUNC|O_CREAT,0666);if(fd < 0){perror("fail to open file");return -1;}int n = 0;while((n = recvfrom(clifd,&msg,sizeof(msg),0,NULL,NULL)) > 0){if(msg.type == 0){break;}write(fd,msg.buf,msg.type);memset(&msg,0,sizeof(msg));}close(fd);
    close(clifd);
    return 0;
    }
    
  • 服務器端

    int main(){int serfd = socket(AF_INET,SOCK_DGRAM,0);if(serfd < 0){perror("socket fail");return -1;}struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = INADDR_ANY;if(bind(serfd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0){perror("fail to bind");return -1;}DIR *dir;struct dirent *dp;msg_t msg;struct sockaddr_in cliaddr;socklen_t len = sizeof(cliaddr);dir = opendir("/home/linux/桌面");if(dir == NULL){perror("fail to open dir");return -1;}recvfrom(serfd,msg.buf,sizeof(msg.buf),0,(struct sockaddr*)&cliaddr,&len);printf("buf = %s\n",msg.buf);while(1){dp = readdir(dir);if(dp == NULL){perror("fail to read dir");return -1;}else if('.' == dp->d_name[0]){continue;}else if(strcmp(dp->d_name,msg.buf) == 0){sprintf(msg.buf,"/home/linux/桌面/%s",dp->d_name);int fd = open(msg.buf,O_RDONLY);if(fd < 0){perror("fail to open file");return -1;}int n;while((n = read(fd,msg.buf,sizeof(msg.buf))) > 0){msg.type = n;sendto(serfd,&msg,sizeof(msg),0,(const struct sockaddr*)&cliaddr,sizeof(cliaddr));}msg.type = 0;sendto(serfd,&msg,sizeof(msg),0,(const struct sockaddr*)&cliaddr,sizeof(cliaddr));close(fd);break;}}closedir(dir);
    close(serfd);
    return 0;
    }
    

2.用UDP實現服務器端和客戶端的點對點聊天

  • 客戶端

    int clifd;
    struct sockaddr_in seraddr;
    socklen_t len = sizeof(seraddr);void *thread1(void* arg){char buf[1024];while(1){memset(buf,0,sizeof(buf));recvfrom(clifd,buf,sizeof(buf),0,(struct sockaddr*)&seraddr,&len);if(strcmp(buf,".quit") == 0){printf("server quit\n");break;}printf("server say:%s\n",buf);}return NULL;
    }
    void *thread2(void* arg){char buf[1024];while(1){memset(buf,0,sizeof(buf));fgets(buf,sizeof(buf),stdin);if(strcmp(buf,".quit\n") == 0){break;}sendto(clifd,buf,strlen(buf)+1,0,(struct sockaddr*)&seraddr,sizeof(seraddr));}return NULL;
    }int main(){clifd = socket(AF_INET,SOCK_DGRAM,0);if(clifd < 0){perror("fail to socket");return -1;}memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");pthread_t pid1;pthread_t pid2;void *(*p1)(void*) = thread1;void *(*p2)(void*) = thread2;pthread_create(&pid1,NULL,p1,NULL);pthread_create(&pid2,NULL,p2,NULL);pthread_join(pid1,NULL);pthread_join(pid2,NULL);close(clifd);return 0;
    }
    
  • 服務器端

    int serfd;
    struct sockaddr_in seraddr;struct sockaddr_in cliaddr;
    socklen_t len = sizeof(cliaddr);void *thread1(void* arg){char buf[1024];while(1){memset(buf,0,sizeof(buf));recvfrom(serfd,buf,sizeof(buf),0,(struct sockaddr*)&cliaddr,&len);if(strcmp(buf,".quit") == 0){printf("client quit\n");break;}printf("client say:%s\n",buf);}return NULL;
    }
    void *thread2(void* arg){char buf[1024];while(1){memset(buf,0,sizeof(buf));fgets(buf,sizeof(buf),stdin);if(strcmp(buf,".quit\n") == 0){break;}sendto(serfd,buf,strlen(buf)+1,0,(struct sockaddr*)&cliaddr,len);}return NULL;
    }int main(){serfd = socket(AF_INET,SOCK_DGRAM,0);if(serfd < 0){perror("fail to socket");return -1;}memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = INADDR_ANY;if(bind(serfd,(const struct sockaddr*)&seraddr,sizeof(seraddr))< 0){perror("fail to bind");return -1;}pthread_t pid1;pthread_t pid2;void *(*p1)(void*) = thread1;void *(*p2)(void*) = thread2;pthread_create(&pid1,NULL,p1,NULL);pthread_create(&pid2,NULL,p2,NULL);pthread_join(pid1,NULL);pthread_join(pid2,NULL);close(serfd);return 0;
    }
    

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/94301.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/94301.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/94301.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

為什么給數據表加了索引,寫入速度反而變慢了

為數據表增加索引后之所以會導致寫入&#xff08;包括插入、更新、刪除&#xff09;操作的速度變慢&#xff0c;其根本原因在于索引本質上是一個獨立的、需要與主表數據保持實時同步的“數據結構”。這一機制的核心邏輯涵蓋五個方面&#xff1a;因為索引本質上是一個“獨立的數…

.NET Core 中采用獨立數據庫的SAAS(多租戶)方法

介紹多租戶是指一種軟件架構&#xff0c;其中軟件的單個實例在服務器上運行并為多個租戶提供服務。在基于 SAAS 的平臺中&#xff0c;租戶是指使用該平臺開展業務運營的客戶。每個租戶都擁有獨立的數據、用戶帳戶和配置設置&#xff0c;并且與其他租戶隔離。多租戶允許有效利用…

運維日常工作100條

這是一份非常詳細和實用的“運維日常工作100條”清單。它涵蓋了從日常巡檢、變更管理、故障處理到安全、優化和文檔等運維工作的方方面面,可以作為運維工程師的日常工作指南和檢查清單。 運維日常工作100條 一、日常巡檢與監控 (20條) 檢查核心監控大盤:查看整體業務健康狀態…

OpenHarmony子系統介紹

OpenHarmony子系統OpenHarmony子系統1. AI業務子系統2. 方舟運行時子系統3. ArkUI框架子系統4. DFX子系統5. DeviceProfile子系統6. XTS子系統7. 上傳下載子系統8. 主題框架子系統9. 事件通知子系統10. 位置服務子系統11. 元能力子系統12. 全局資源調度子系統13. 全球化子系統1…

博士招生 | 英國謝菲爾德大學 招收計算機博士

內容源自“圖靈學術博研社”gongzhonghao學校簡介謝菲爾德大學&#xff08;The University of Sheffield&#xff09;是英國久負盛名的公立研究型大學&#xff0c;也是羅素集團成員之一。在 2026 年 QS 世界大學排名中&#xff0c;謝菲爾德大學位列第92位&#xff0c;其中計算機…

如何理解面向過程和面向對象,舉例說明一下?

面向過程和面向對象是兩種不同的編程思想&#xff0c;核心區別在于解決問題的視角不同&#xff1a;前者關注 “步驟和過程”&#xff0c;后者關注 “對象和交互”。面向過程的核心思想是把問題拆解成一系列步驟&#xff0c;通過函數實現每個步驟&#xff0c;然后按順序調用這些…

深入了解評估與微調中使用的Graders:原理、實現與最佳實踐

深入了解評估與微調中使用的Graders 在模型評估與微調&#xff08;Fine-tuning&#xff09;過程中&#xff0c;Graders&#xff08;評分器&#xff09;是衡量模型輸出與參考答案之間表現的重要工具。本文將系統介紹Grader的類型、技術實現及如何在實際項目中融入穩定且高質量的…

行緩存(line buffer)在圖像卷積中的工作方式

上面這張圖配合文字&#xff0c;展示了行緩存&#xff08;line buffer&#xff09;在圖像卷積中的工作方式&#xff1a;上半部分是一個按行掃描輸入的圖像塊&#xff08;示例為 99&#xff0c;編號 1–81&#xff09;。 藍色表示已被寫入行緩存并按隊列等待的數據&#xff0c;綠…

【數據分享】中國371個城市的坡度矢量數據和excel數據

今天要說明數據就是中國371個城市的坡度矢量數據和excel數據。數據介紹在城市發展的進程中&#xff0c;地形地貌始終是影響規劃決策的關鍵因素&#xff0c;而坡度作為表征地表傾斜程度的核心指標&#xff0c;更是貫穿于城市建設、生態保護等諸多環節。本文將全面解讀中國 371 個…

《WINDOWS 環境下32位匯編語言程序設計》第7章 圖形操作(1)

圖形設備接口GDI&#xff08;Graphics Device Interface&#xff09;是Win32的一個重要組成部分&#xff0c;其作用是允許Windows的應用程序將圖形輸出到計算機屏幕、打印機或其他輸出設備上。GDI實際上是一個函數庫&#xff0c;包括直線、畫圖和字體處理等數百個函數。7.1 GDI…

數據結構-HashMap

在 Java 鍵值對&#xff08;Key-Value&#xff09;集合中&#xff0c;HashMap 是使用頻率最高的實現類之一&#xff0c;憑借高效的查找、插入性能&#xff0c;成為日常開發的 “利器”。本文將從 HashMap 的底層原理、核心特點、常用方法到遍歷方式、使用注意事項&#xff0c;進…

[系統架構設計師]安全架構設計理論與實踐(十八)

[系統架構設計師]安全架構設計理論與實踐&#xff08;十八&#xff09; 一.信息安全面臨的威脅 1.信息系統安全威脅的來源 物理環境&#xff0c;通信鏈路&#xff0c;網絡系統&#xff0c;操作系統&#xff0c;應用系統&#xff0c;管理系統 2.網絡與信息安全風險類別 風險類別…

AI適老服務暖人心:AI適老機頂盒破數字鴻溝、毫米波雷達護獨居安全,銀發生活新保障

銀發經濟領域長期受限于 “專業照護資源稀缺”“老年人數字適應能力弱”“獨居老人安全隱患多” 的困境&#xff0c;而 AI 技術的適老化改造&#xff0c;正讓銀發服務從 “被動保障” 轉向 “主動關懷”&#xff0c;既能幫老年人跨越數字鴻溝&#xff0c;又能為獨居老人筑起安全…

Linux應用軟件編程---網絡編程1(目的、網絡協議、網絡配置、UDP編程流程)

Linux下的網絡編程一、目的不同主機&#xff0c;進程間通信。二、解決的問題1. 主機與主機之間物理層面必須互聯互通。 2. 進程與進程在軟件層面必須互聯互通。物理層面的互聯互通流程圖如下&#xff1a;其中&#xff1a;IP地址&#xff1a;計算機的軟件地址&#xff0c;用來標…

常見開源協議詳解:哪些行為被允許?哪些被限制?

常見開源協議詳解&#xff1a;哪些行為被允許&#xff1f;哪些被限制&#xff1f; 開源世界的魅力在于共享與合作&#xff0c;但不同的開源協議對分發、修改、再發布以及宣傳/推廣有不同的要求和限制。很多開發者在 fork 項目、改 README、放到自己倉庫并在自媒體傳播 時&…

服務器硬盤進行分區和掛載

查看服務器上的硬盤&#xff1a;lsblk -d -o NAME,SIZE,MODEL可以看到我的硬盤是除了vda系統盤以外&#xff0c;還有個vdb。我們查看一下分區&#xff1a;lsblk可以看到&#xff1a;vdb 1T disk &#xff08;底下沒有分區&#xff0c;也沒有掛載&#xff09;我們想要用起來這…

【C初階】數據在內存中的存儲

目錄 1. 整數在內存中的存儲 2. 大小端字節序 2.1 什么是大小端&#xff1f; 2.2 為什么有大小端&#xff1f; 2.3 練習 2.3.1 練習1 2.3.2 練習2 2.3.3 練習3 2.3.4 練習4 2.3.5 練習5 2.3.6 練習6 3. 浮點數在內存中的存儲 3.1 浮點數存儲的過程 3.2 浮點數的取…

AI 自動化編程 trae 體驗2 幫我分析一個項目

總結&#xff1a; 接手一個項目可以讓trae 幫忙分析 上次講到trae在處理組件引入的時候&#xff0c;經常會碰到版本問題&#xff0c;分析引入了互聯網上非本版本或者有bug的代碼。主要依賴互聯網的資源庫。 但是分析一個項目應該是沒問題。 這次表現非常好&#xff0c;接手一個…

VMware虛擬機中CentOS 7 報錯 ping: www.xxx.com: Name or service not known

1:主要原因是網絡配置的問題 2:其實就是下面三張圖片中的,物理機虛擬網卡 vmware8 和虛擬機網絡編輯器&#xff0c;如果設置靜態IP 就是這三個地方的問題最簡單的解決辦法第一步&#xff1a;還原虛擬機網絡點擊確認后 ** 第二步給自己的虛擬機設置網絡連接方式 選擇NAT模式連接…

Java面試-自動裝箱與拆箱機制解析

&#x1f44b; 歡迎閱讀《Java面試200問》系列博客&#xff01; &#x1f680;大家好&#xff0c;我是Jinkxs&#xff0c;一名熱愛Java、深耕技術一線的開發者。在準備和參與了數十場Java面試后&#xff0c;我深知面試不僅是對知識的考察&#xff0c;更是對理解深度與表達能力的…