華清遠見嵌入式學習——網絡編程——小項目

項目要求:

代碼實現:

服務器端:

#include <myhead.h>//定義協議包
struct proto
{char type;char name[20];char text[128];	
};int main(int argc, const char *argv[])
{//判斷從終端輸入的字符串的個數if(argc != 3){printf("input error\n");printf("usage:./a.out 本機IP 本機端口\n");return -1;}//創建用于通信的套接字int sfd = socket(AF_INET,SOCK_DGRAM,0);if(sfd == -1){perror("socket error");return -1;}//設置端口號快速重用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){perror("setsockopt error");return -1;}//綁定服務器IP和端口號填充服務器地址信息結構體short port = (short)atoi(argv[2]);struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_addr.s_addr = inet_addr(argv[1]);sin.sin_port = htons(port);綁定if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin)) == -1){perror("bind error");return -1;}//定義客戶端地址信息結構體struct sockaddr_in cin;cin.sin_family = AF_INET;socklen_t socklen = sizeof(cin);//定義客戶端地址信息結構體數組,用于存放多個客戶端地址信息struct sockaddr_in savecin[1024];//初始化每個信息結構體內的第一個成員for(int i = 0;i < 1024;i++){savecin[i].sin_family = AF_INET;}定義一個用于檢測文件描述符的集合fd_set readfds, tempfds;                          //在棧區定義清空容器中的內容FD_ZERO(&readfds);將要檢測的文件描述符放入集合中FD_SET(sfd, &readfds);           //將sfd文件描述符放入FD_SET(0, &readfds);             //將0號文件描述符放入//對客戶端的數據進行保存和轉發char buf[256] = "";int res1,res2;int n = 0;//定義協議包結構體變量struct proto pro;struct proto send;while(1){bzero(buf,sizeof(buf));tempfds = readfds;使用select阻塞等待集合中的文件描述符有事件產生res1 = select(sfd+1, &tempfds, NULL, NULL, NULL);if(res1 == -1){perror("select error");return -1;}else if(res1 == 0){printf("time out\n");return -1;}//接收客戶端信息if(FD_ISSET(sfd,&tempfds)){res2 = recvfrom(sfd,&pro,sizeof(pro),0,(struct sockaddr *)&cin,&socklen);if(res2 == -1){perror("recvfrom error");return -1;}//登錄時存儲客戶端到數組中if(pro.type == 'L'){savecin[n] = cin;n++;sprintf(buf,"---%s已上線---",pro.name);printf("%s\n",buf);for(int i = 0;i < n;i++){if(savecin[i].sin_port == cin.sin_port){continue;}	sendto(sfd,&pro,sizeof(pro),0,(struct sockaddr *)&savecin[i],sizeof(savecin[i]));}}if(pro.type == 'C'){//群聊send.type = pro.type;strcpy(send.name,pro.name);strcpy(send.text,pro.text);for(int i = 0;i < n;i++){if(savecin[i].sin_port == cin.sin_port){continue;}	sendto(sfd,&send,sizeof(send),0,(struct sockaddr *)&savecin[i],sizeof(savecin[i]));}}if(pro.type == 'Q'){//下線send.type = pro.type;strcpy(send.name,pro.name);strcpy(send.text,pro.text);for(int i = 0;i < n;i++){bzero(buf,sizeof(buf));sprintf(buf,"---%s已下線---\n",send.name);printf("%s\n",buf);//刪除該用戶if(savecin[i].sin_port == cin.sin_port){int t = i;for(int j = i;j <= n;j++){savecin[t] = savecin[t+1];t++;				}}n--;sendto(sfd,&send,sizeof(send),0,(struct sockaddr *)&savecin[i],sizeof(savecin[i]));}}}if(FD_ISSET(0,&tempfds)){bzero(send.name,sizeof(send.name));bzero(send.text,sizeof(send.text));send.type = 'C';strcpy(send.name,"系統消息");fgets(send.text,sizeof(send.text),stdin);send.text[strlen(send.text)-1] = '\0';for(int i = 0;i <= n;i++){sendto(sfd,&send,sizeof(send),0,(struct sockaddr *)&savecin[i],sizeof(savecin[i]));}	}}//關閉套接字文件描述符close(sfd);return 0;
}

客戶端:

#include <myhead.h>//定義協議包結構體
struct proto
{char type;char name[20];char text[128];
};int main(int argc, const char *argv[])
{//判斷終端輸入的字符串的個數if(argc != 3){printf("input error\n");printf("usage:./a.out 服務器IP 服務器端口號\n");return -1;}//創建用于通信的套接字int cfd = socket(AF_INET,SOCK_DGRAM,0);if(cfd == -1){perror("socket error");return -1;}//填充服務器地址信息結構體short port = (short)atoi(argv[2]);	struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_addr.s_addr = inet_addr(argv[1]);sin.sin_port = htons(port);socklen_t socklen = sizeof(sin);//定義協議包結構體變量struct proto pro;//填充登錄協議printf("請輸入姓名>>");//登錄pro.type = 'L'; fgets(pro.name,sizeof(pro.name),stdin);pro.name[strlen(pro.name)-1] = '\0';sendto(cfd,&pro,sizeof(pro),0,(struct sockaddr *)&sin,sizeof(sin));定義一個用于檢測文件描述符的集合fd_set readfds, tempfds;                          //在棧區定義清空容器中的內容FD_ZERO(&readfds);將要檢測的文件描述符放入集合中FD_SET(cfd, &readfds);           //將sfd文件描述符放入FD_SET(0, &readfds);             //將0號文件描述符放入//向服務器發送或從服務器接收消息char rbuf[128] = "";int res = 0;char name1[20] = "";strcpy(name1,pro.name);while(1){將集合內容復制一份tempfds = readfds;使用select阻塞等待集合中的文件描述符有事件產生res = select(cfd+1, &tempfds, NULL, NULL, NULL);if(res == -1){perror("select error");return -1;}else if(res == 0){printf("time out\n");return -1;}//群聊和退出if(FD_ISSET(0,&tempfds)){bzero(pro.text,sizeof(pro.text));//從終端獲取內容fgets(pro.text,sizeof(pro.text),stdin);pro.text[strlen(pro.text)-1] = '\0';if(strcmp(pro.text,"quit") == 0){//退出pro.type = 'Q';sendto(cfd,&pro,sizeof(pro),0,(struct sockaddr *)&sin,sizeof(sin));//關閉套接字文件描述符close(cfd);break;}else{//群聊pro.type = 'C';sendto(cfd,&pro,sizeof(pro),0,(struct sockaddr *)&sin,sizeof(sin));}}//接收來自服務器的消息if(FD_ISSET(cfd,&tempfds)){bzero(rbuf,sizeof(rbuf));bzero(pro.text,sizeof(pro.text));res = recvfrom(cfd,&pro,sizeof(pro),0,NULL,NULL);if(res < 0){perror("recvfrom error");return -1;}if(pro.type == 'L'){printf("---%s已登錄---\n",pro.name);}if(pro.type == 'C'){printf("%s:%s\n",pro.name,pro.text);if(strcmp(pro.name,"系統消息") == 0){strcpy(pro.name,name1);}}if(pro.type == 'Q'){printf("---%s已下線---\n",pro.name);}}}//關閉套接字文件描述符close(cfd);return 0;
}

代碼運行效果圖:

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

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

相關文章

mysql中TIMESTAMP 和DATETIME數據類型的區別

在MySQL中&#xff0c;TIMESTAMP和DATETIME都用于表示日期和時間&#xff0c;但是它們之間存在一些關鍵區別。下面我們通過幾個關鍵點來詳細了解這兩種數據類型的使用&#xff1a; 存儲范圍 TIMESTAMP類型的存儲范圍從1970-01-01 00:00:01 UTC到2038-01-19 03:14:07 UTC。DAT…

Django之importlib模塊

【1】介紹 import importlib importlib模塊是Python中用于動態加載和導入模塊的內置模塊 它提供了一組函數和類&#xff0c;使得我們可以在運行時根據需要加載模塊&#xff0c;并且可以對已導入的模塊進行操作和管理 【2】importlib模塊中的import_module方法 【2.1】導入模塊…

無需API開發,錢方QFPay連接營銷系統和廣告推廣平臺

隨著電子商務市場的不斷發展&#xff0c;企業需要集成各種業務系統&#xff0c;以提高業務效率和降低運營成本。錢方QFPay提供了一種創新的解決方案&#xff0c;幫助企業實現系統間的連接和集成&#xff0c;無需進行復雜的API開發。除了電商系統和客服系統&#xff0c;錢方還能…

武漢光庭公司地圖引擎開發工程師24秋招三場面試完整流程

本文介紹2024屆秋招中&#xff0c;武漢光庭信息技術股份有限公司的智能駕駛地圖引擎開發工程師崗位一面、二面、三面的面試基本情況、提問問題等。 10月投遞了武漢光庭信息技術股份有限公司的智能駕駛地圖引擎開發工程師崗位&#xff0c;暫時并不清楚所在的部門。目前完成了全部…

mysql:修改密碼的幾種方式

背景 當我們 brew install mysql 新安裝 mysql 的時候&#xff0c;是沒有密碼的&#xff0c;我們可以直接通過 mysql -u root 連接上。但是密碼還是要設置的&#xff0c;一是為了安全&#xff0c;二是有些數據庫軟件如 Sequel 連接都是必須要密碼的&#xff0c;接下來我們來看…

電磁建模的分布式并行計算技術

本文提出了一種新的分布式并行電磁建模技術&#xff0c;以加快電磁結構的神經網絡建模過程。現有的電磁建模技術通常需要反復改變微波器件的參數&#xff0c;驅動電磁模擬器以獲得足夠的訓練和測試樣本。隨著電磁建模問題復雜性的增加&#xff0c;由于單臺計算機的性能有限&…

DP好題總結

LCIS最長公共上升子序列 題解&#xff1a;https://blog.csdn.net/weixin_50624971/article/details/116892236 概括&#xff1a; 決策優化DP 考慮LCS可以寫成 O ( n 4 ) O(n^4) O(n4) 的如果我們把狀態設為 f [ i , j ] f[i,j] f[i,j] 表示考慮到 a [ i ] , b [ j ] a[i]…

機器學習【00】pycharm使用遠程服務器

我們使用conda在服務器上創建虛擬環境&#xff0c;遠程使用pycharm進行編程 pycharm版本2023.1.3 一.首先在服務器上創建虛擬環境 注&#xff1a;anaconda的安裝可以參考ubuntu系統miniconda的安裝 conda create --name tac python3.7二.pycharm 連接 點擊add interpreter …

查企業聯系電話的方法

對于銷售來說&#xff0c;獲取準確、全面的企業聯系方式&#xff0c;無疑是開發客戶的基礎與保障&#xff0c;因為任憑能力再高&#xff0c;說服能力多強&#xff0c;沒有與客戶接觸的機會&#xff0c;這些都是無稽之談。但是大家都知道&#xff0c;道理都懂&#xff0c;但是要…

.yaml文件的簡介

文章目錄 YAML文件簡介YAML文件的示例 YAML文件簡介 YAML是一種人類可讀的數據序列化標準。它常被用于配置文件、數據交換格式、以及在一些編程語言中的數據結構描述。 YAML 文件的主要特點有如下四點&#xff1a; 可讀性&#xff1a;YAML 的語法結構簡潔明了&#xff0c;容…

報錯AttributeError: module ‘cv2‘ has no attribute ‘ximgproc‘

報錯AttributeError: module ‘cv2’ has no attribute ‘ximgproc’ 首先查看是否安裝opencv-contrib-python pip list | grep opencv顯示 opencv-contrib-python 4.4.0.46 opencv-python 4.8.1.78 opencv-pyt…

【2023.11.24】Mybatis基本連接語法學習?

基本配置 1.如果使用Maven管理項目&#xff0c;需要在pom.xml中配置依賴。 2.安裝Mybatis-3.5.7.jar包 3.進行XML配置&#xff1a;這里將文件命名為mybatis-config.xml 配置數據庫連接XML文件 <?xml version"1.0" encoding"UTF-8" ?> <!DO…

Crypto(10)BUUCTF-RSA3(共模攻擊)

一.共模攻擊的現實意義 好奇一個問題&#xff0c;即共模攻擊有什么現實意義&#xff1f; 發現也沒有什么現實意義&#xff0c;因為&#xff08;n,e&#xff09;是已知的&#xff0c;通常每個用戶的n是不同的&#xff0c;除非特殊情況吧 二.共模攻擊的數學原理&#xff1a; 通…

最重要的BI測試-適用于任何BI和分析平臺

為什么 BI 測試是答案 相信你的數據可視化是成功執行商業智能 (BI) 和分析項目的關鍵因素。我敢肯定&#xff0c;你遇到過以下情況&#xff1a;業務主管或業務用戶反饋說他們的分析看起來不對&#xff0c;他們的 KPI 看起來有問題&#xff0c;或者速度太慢而無法使用。要問自己…

SQL 通配符:用于模糊搜索和匹配的 SQL 關鍵技巧

SQL通配符字符 通配符字符用于替代字符串中的一個或多個字符。通配符字符與LIKE運算符一起使用。LIKE運算符用于在WHERE子句中搜索列中的指定模式。 示例 返回所有以字母 ‘a’ 開頭的客戶&#xff1a; SELECT * FROM Customers WHERE CustomerName LIKE a%;通配符字符 符…

5:kotlin 類(Classes )

kotlin支持面向對象編程&#xff0c;也有雷和對象的概念 要聲明一個類需要使用class關鍵字 class Customer屬性&#xff08;Properties&#xfeff;&#xff09; 可以在類名后邊添加()&#xff0c;在()里邊聲明屬性 class Contact(val id: Int, var email: String)聲明了不…

單片機、ARM、嵌入式開發、Android 底層開發有什么關系?

單片機、ARM、嵌入式開發、Android 底層開發有什么關系&#xff1f; 從我目前的見識來看&#xff1a; 單片機是個系統&#xff08;比如&#xff1a;51、AVR、PLC...&#xff09;&#xff0c;其中包含了去除了輸入輸出之外的運算器、控制器、存儲器&#xff0c;我們用程序可以非…

從Redis反序列化UserDetails對象異常后發現FastJson序列化的一些問題

最近在使用SpringSecurityJWT實現認證授權的時候&#xff0c;出現Redis在反序列化userDetails的異常。通過實踐發現&#xff0c;使用不同的序列化方法和不同的fastJson版本&#xff0c;異常信息各不相同。所以特地記錄了下來。 一、項目代碼 先來看看我項目中redis相關配置信息…

黑馬點評筆記 redis緩存三大問題解決

文章目錄 緩存問題緩存穿透問題的解決思路編碼解決商品查詢的緩存穿透問題 緩存雪崩問題及解決思路緩存擊穿問題及解決思路問題分析使用鎖來解決代碼實現 邏輯過期方案代碼實現 緩存問題 我們熟知的是用到緩存就會遇到緩存三大問題&#xff1a; 緩存穿透緩存擊穿緩存雪崩 接…

QOverload獲取重載的信號

QOverload獲取重載的信號 多個信號或者函數同名&#xff0c;但是不同參數&#xff0c;也就是存在重載 可以使用QOverload獲取指定的重載函數 QOverload<int>::of(&QComboBox::currentIndexChanged)上面的代碼就是用來獲取參數為int的那個函數