41、網絡編程/TCP.UDP通信模型練習20240301

一、編寫基于TCP的客戶端實現以下功能:

通過鍵盤按鍵控制機械臂:w(紅色臂角度增大)s(紅色臂角度減小)d(藍色臂角度增大)a(藍色臂角度減小)按鍵控制機械臂

1.基于TCP服務器的機械臂,端口號是8888, ip是Windows的ip;

查看Windows的IP:按住Windows+r 按鍵,輸入cmd , 輸入ipconfig。

2.點擊軟件中的開啟監聽;

3.機械臂需要發送16進制數,共5個字節,協議如下

0xff    0x02    x   y   0xff
0xff:起始結束協議,固定的;
0x02:控制機械手臂協議,固定的;
x:指定要操作的機械臂0x00 紅色擺臂0x01 藍色擺臂
y:指定角度

代碼:

#include<myhead.h>
#define SER_IP "192.168.125.64"  //服務器IP
#define SER_PORT 8888          //服務器端口號
int main(int argc, const char *argv[])
{//創建套接字文件int sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd==-1){perror("socket error");return -1;}//定義結構體存儲服務器地址struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);//連接服務器if(connect(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("connect error");return -1;}puts("connect success");//數據發送//定義控制紅色臂的數組并初始化,范圍是[-90,90]char rbuf[5]={0xff,0x02,0x00,0x00,0xff};//定義控制藍色臂的數組并初始化,范圍是[0,180]unsigned char bbuf[5]={0xff,0x02,0x01,0x00,0xff};//發送初始值send(sfd,rbuf,sizeof(rbuf),0);sleep(1);//防止沾包send(sfd,bbuf,sizeof(bbuf),0);char key=0;while(1){system("stty -icanon");//關閉緩沖區key=getchar();fflush(stdin);switch(key){case 'W':case 'w':{rbuf[3]+=2;//每次操作的角度偏移2度if(rbuf[3]>=90){rbuf[3]=90;}send(sfd,rbuf,sizeof(rbuf),0);}break;case 'S':case 's':{rbuf[3]-=2;if(rbuf[3]<=-90){rbuf[3]=-90;}send(sfd,rbuf,sizeof(rbuf),0);}break;case 'D':case 'd':{bbuf[3]+=2;if(bbuf[3]>=180){bbuf[3]=180;}send(sfd,bbuf,sizeof(bbuf),0);}break;case 'A':case 'a':{bbuf[3]-=2;if(bbuf[3]>180)//無符號整數小于零后會向255循環{bbuf[3]=0;}send(sfd,bbuf,sizeof(bbuf),0);}break;}}close(sfd);return 0;
}

運行:

思維導圖

二、 基于UDP的TFTP文件傳輸

1.tftp協議概述

簡單文件傳輸協議,適用于在網絡上進行文件傳輸的一套標準協議,使用UDP傳輸

特點:

是應用層協議

基于UDP協議實現

數據傳輸模式

octet:二進制模式(常用)

mail:已經不再支持

2.tftp下載模型

TFTP通信過程總結

  1. 服務器在69號端口等待客戶端的請求
  2. 服務器若批準此請求,則使用 臨時端口 與客戶端進行通信。
  3. 每個數據包的編號都有變化(從1開始)
  4. 每個數據包都要得到ACK的確認,如果出現超時,則需要重新發送最后的數據包或ACK包
  5. 數據長度以512Byte傳輸的,小于512Byte的數據意味著數據傳輸結束。

差錯碼:

0 未定義,差錯錯誤信息

1 File not found.

2 Access violation.

3 Disk full or allocation exceeded.

4 illegal TFTP operation.

5 Unknown transfer ID.

6 File already exists.

7 No such user.

8 Unsupported option(s) requested.

代碼:

#include<myhead.h>
#define SER_IP "192.168.125.57"
#define SER_POTR 69
int my_download(int cfd,struct sockaddr_in sin);
int my_upload(int cfd,struct sockaddr_in sin);
int my_save_data(char *p,int len);
int recv_ack(int cfd,struct sockaddr_in sin);int main(int argc, const char *argv[])
{//創建通信套接字int cfd=socket(AF_INET,SOCK_DGRAM,0);if(cfd==-1){perror("socket error");return -1;}//定義地址結構體 保存客戶端地址struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_POTR);sin.sin_addr.s_addr=inet_addr(SER_IP);int menu=0;while(1){system("clear");puts("\t\t------請選擇選項------");printf("\t\t-------1.上傳-------\n");printf("\t\t-------2.下載-------\n");printf("\t\t-------0.退出-------\n");scanf("%d",&menu);getchar();switch(menu){case 0:goto END;case 1:{int res=my_upload(cfd,sin);if(res==-1){puts("my_upload error");return -1;}}break;case 2:{int res=my_download(cfd,sin);if(res==-1){puts("my_download error");return -1;}}break;default:{puts("輸入有誤,請重新輸入");}break;}puts("請輸入任意鍵按回車結束!");while(getchar()!='\n');}END:close(cfd);return 0;
}int my_download(int cfd,struct sockaddr_in sin)
{//定義收發數據容器char pack[516]="";//組建請求協議包//1.請求下載printf("請輸入要下載的文件名:");char txt[32]="";fgets(txt,sizeof(txt),stdin);txt[strlen(txt)-1]=0;short *p1=(short*)pack;*p1=htons(1);//存入前兩字節的操作碼1代表讀(下載)char *p2=pack+2;strcpy(p2,txt);//存入文件名及結尾的0char *p3=p2+strlen(p2)+1;strcpy(p3,"octet");//存入模式位及結尾的0int packlen=4+strlen(p2)+strlen(p3);//發送下載請求if(sendto(cfd,pack,packlen,0,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("download request sendto error");return -1;}
/*	//讀取服務器的回復消息int ack=recv_ack(cfd,sin);if(ack==-1){puts("recv_ack error");return -1;}
*/while(1){bzero(pack,sizeof(pack));int ack=recv_ack(cfd,sin);if(ack==-1){puts("my_download recv_ack error");return -1;}else if(ack==0)//下載完成{break;}*p1=htons(4);//設置ACK包*(p1+1)=htons(ack);//返回ACK包if(sendto(cfd,pack,sizeof(pack),0,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("upload request sendto error");return -1;}	}return 0;
}
int my_upload(int cfd,struct sockaddr_in sin)
{//定義收發數據容器char pack[516]="";//組建請求協議包//1.請求寫入printf("請輸入要上傳的文件名:");char txt[32]="";fgets(txt,sizeof(txt),stdin);txt[strlen(txt)-1]=0;short *p1=(short*)pack;*p1=htons(2);//存入前兩字節的操作碼2代表寫(上傳)char *p2=pack+2;strcpy(p2,txt);//存入文件名及結尾的0char *p3=p2+strlen(p2)+1;strcpy(p3,"octet");//存入模式位及結尾的0int packlen=4+strlen(p2)+strlen(p3);if(sendto(cfd,pack,packlen,0,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("upload request sendto error");return -1;}//讀取服務器的回復消息int ack=recv_ack(cfd,sin);if(ack==-1){puts("recv_ack error");return -1;}//2.開始上傳數據//2.1只讀形式打開要上傳的文件int rfd=open(txt,O_RDONLY);if(rfd==-1){perror("upload open error");return -1;}int i=1;while(1){bzero(pack,sizeof(pack));//2.2設置發送數據的協議包*p1=htons(3);//前兩字節操作碼為3時代表此為數據包*(p1+1)=htons(i);//設置塊編碼從1開始int res=read(rfd,pack+4,512);//從文件中讀取512數據存入數據域packlen=4+res;//本次的數據包大小//發送數據if(sendto(cfd,pack,sizeof(pack),0,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("upload data sandto error");return -1;}ack=recv_ack(cfd,sin);//讀取服務器的回復消息if(ack==-1){puts("recv_ack error");return -1;}else if(ack<i)//服務器返回的塊編碼小于當前發送的{//光標返回發送之前的位置重新發送lseek(rfd,-res,SEEK_CUR);}else if(ack==i)//服務器已接收該數據包可以發送下一個{i++;//塊編碼+1}if(res<512)//發送完成{break;}}close(rfd);return 0;
}
int my_save_data(char *p,int len)
{//追加寫的形式創建一個文件存儲下載的數據int wfd=open("./downtxt",O_WRONLY|O_APPEND|O_CREAT,0664);if(wfd==-1){perror("my_download open error");return -1;}write(wfd,p,len);close(wfd);return 0;
}
int recv_ack(int cfd,struct sockaddr_in sin)
{char pack[516]="";//接收服務器發來的消息 存入packint sinlen=sizeof(sin);int res=-1;if((res=(recvfrom(cfd,pack,sizeof(pack),0,(struct sockaddr*)&sin,&sinlen)))==-1){perror("recv_ack recvfrom error");return -1;}short *p=(short*)pack;short num=ntohs(*p);//獲取發來消息的操作碼switch(num){case 3:{printf("收到數據包,塊編碼:%d\n",ntohs(*(p+1)));//保存數據int seve=my_save_data(pack+4,res-4);if(seve==-1){puts("my_save_data error");return -1;}//如果讀取的長度小于516說明已經下載完成if(res<sizeof(pack)){//最后一次回復ACK*p=htons(4);sendto(cfd,pack,4,0,(struct sockaddr*)&sin,sizeof(sin));return 0;//正常下載完成返回0}}break;case 4:{printf("收到ACK,快編碼:%d\n",ntohs(*(p+1)));}break;case 5:{//收到錯誤碼 輸出差錯碼和差錯信息printf("ERROR:%d:%s\n",ntohs(*(p+1)),pack+4);return -1;}break;}return ntohs(*(p+1));//返回塊編碼
}

?

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

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

相關文章

Java 創建對象有哪幾種方式

1. 使用new關鍵字&#xff1a;這是最常見和最簡單的創建對象的方式。你可以通過這種方式調用任意的構造函數&#xff0c;無論是無參的還是有參數的構造函數。 例如&#xff1a; Student stu new Student 2. 使用Class類的newInstance方法&#xff08;反射&#xff09; 這種…

Python3零基礎教程之數學運算專題進階

大家好,我是千與編程,今天已經進入我們Python3的零基礎教程的第十節之數學運算專題進階。上一次的數學運算中我們介紹了簡單的基礎四則運算,加減乘除運算。當涉及到數學運算的 Python 3 刷題使用時,進階課程包含了許多重要的概念和技巧。下面是一個簡單的教程,涵蓋了一些常…

勒索軟件類型

勒索軟件類型 加密勒索軟件 它使個人文件和文件夾&#xff08;文檔、電子表格、圖片和視頻&#xff09;被加密。受感染的文件被加密后會被刪除&#xff0c;用戶通常會在當下無法使用的文件的文件夾中看到一個包含付款說明的文本文件。當您嘗試打開其中一個加密文件時,您才可能…

Tomcat負載均衡、動靜分離

目錄 引言 實驗圖解 1.實驗環境搭建 2.部署Nginx服務器及配置靜態頁面Web服務 3.部署Tomcat服務及配置動態頁面Web服務 4.實驗驗收 動態頁面 靜態頁面 引言 tomcat服務既可以處理動態頁面&#xff0c;也可以處理靜態頁面&#xff1b;但其處理靜態頁面的速度遠遠不如…

Oracle SQL優化概念之集群因子解析

導讀 本文介紹一個Oracle 數據庫SQL優化的一個基本概念【集群因子】&#xff0c;理解了此概念&#xff0c;有助于對Oracle數據庫進行SQL優化。 1. 集群因子名詞解析 集群因子&#xff08;ClusteringFactor&#xff09;是如果通過一個索引掃描一張表&#xff0c;需要訪問的表的數…

js優雅的統計字符串字符出現次數

題目如下 統計一串字符串中每個字符出現的頻率 示例字符串 let str asdfasqwerqwrdfafafasdfopasdfopckpasdfassfd小白寫法 let str asdfasqwerqwrdfafafasdfopasdfopckpasdfassfdlet result {}; for (let i 0; i < str.length; i) {if (result[str[i]]) {result[str[…

鏈表基礎知識詳解(非常詳細簡單易懂)

概述&#xff1a; 鏈表作為 C 語言中一種基礎的數據結構&#xff0c;在平時寫程序的時候用的并不多&#xff0c;但在操作系統里面使用的非常多。不管是RTOS還是Linux等使用非常廣泛&#xff0c;所以必須要搞懂鏈表&#xff0c;鏈表分為單向鏈表和雙向鏈表&#xff0c;單向鏈表很…

【Vue3】解鎖Vue3黑科技:探索接口、泛型和自定義類型的前端奇跡

&#x1f497;&#x1f497;&#x1f497;歡迎來到我的博客&#xff0c;你將找到有關如何使用技術解決問題的文章&#xff0c;也會找到某個技術的學習路線。無論你是何種職業&#xff0c;我都希望我的博客對你有所幫助。最后不要忘記訂閱我的博客以獲取最新文章&#xff0c;也歡…

Android Compose - PlainTooltipBox(已廢棄)的替代方案

Android Compose - PlainTooltipBox 的替代方案 TooltipBox(positionProvider TooltipDefaults.rememberPlainTooltipPositionProvider(),tooltip {PlainTooltip {Text(/* tooltip content */)}},state rememberTooltipState(), ) {// tooltip anchorIconButton(onClick {…

跨站腳本攻擊xss-labs(1-20)靶機練手

目錄 一、跨站腳本攻擊&#xff08;XSS&#xff09; 1.1 漏洞簡介 1.2:類型 1.3 XSS危害 1.4XSS防御規則 二、環境搭建 三、xsst通關記錄 Level 1&#xff1a;文本解析為 HTML Level 2&#xff1a;htmlspecialchars;input 標簽 value 注入 定義和用法 字符過濾繞過 …

從零自制docker-1-【環境配置 docker go介紹與安裝】

文章目錄 docker簡介舉例docker安裝go語言go安裝go 配置 docker簡介 Docker可以看作是一種極其輕巧的“虛擬機”&#xff0c;它允許你將一個或多個程序及其運行環境打包在一起&#xff0c;形成一個標準化的單元&#xff0c;這個單元可以在任何支持Docker的系統上運行&#xff…

實用!IntelliJ IDEA離線開發使用要點(一)

如果IntelliJ IDEA在本地網絡之外沒有HTTP訪問&#xff0c;它將無法檢查更新和應用補丁。在這種情況下&#xff0c;您必須下載新版本的IDE并按照離線安裝中的描述手動安裝它們。 IDEA v2023.3正式版下載 注意&#xff1a;沒有互聯網接入&#xff0c;您不能安裝IntelliJ IDEA使…

SaaS 電商設計 (九) 動態化且易擴展的實現購物車底部彈層(附:一套普適的線上功能切量的發布方案)

目錄 一.背景1.1 業務背景1.2 技術負債 二.技術目標三.方案設計3.1 解決移動端頻繁發版3.1.1 場景分析3.1.2 技術方案 3.2 減少后端壞味道代碼&無法靈活擴展問題3.2.1 通過抽象接口完成各自單獨樓層渲染邏輯3.2.2 通過配置能力做到部分字段可配 四.升級上線(普適于高并發大…

2314576

? 通用計算機啟動過程 1??一個基礎固件&#xff1a;BIOS 一個基礎固件&#xff1a;BIOS→基本IO系統&#xff0c;它提供以下功能&#xff1a; 上電后自檢功能 Power-On Self-Test&#xff0c;即POST&#xff1a;上電后&#xff0c;識別硬件配置并對其進行自檢&#xff0c…

學習JAVA的第十二天(基礎)

算法 算法&#xff08;Algorithm&#xff09;是指解題方案的準確而完整的描述&#xff0c;是一系列解決問題的清晰指令&#xff0c;算法代表著用系統的方法描述 解決問題的策略 機制。 查找算法 基本查找&#xff08;順序查找&#xff09; 關鍵&#xff1a; 從0索引開始依次向…

學習:吳恩達:什么是神經元?神經網絡如何工作?

學習-吳恩達《AI for everyone》2019 深度學習非技術解釋 第2部分 可選.zh_嗶哩嗶哩_bilibili 深度學習Deep learning 人工神經網絡Artificial Neural network 什么是神經網絡&#xff1f; 只有一個神經元 4個神經元的神經網絡 神經網路的絕妙之處 神經網路的絕妙之處就在…

ctf_show筆記篇(web入門---信息收集)

目錄 信息收集 1-2&#xff1a;查看源代碼 3&#xff1a;bp抓包 4&#xff1a;robots.txt&#xff08;這個文件里會寫有網站管理者不想讓爬蟲的頁面或其他&#xff09; 5&#xff1a;網站源代碼泄露index.phps 6&#xff1a;同樣也是源碼泄露&#xff0c;&#xff08;拿到…

Java快讀

java的快讀 (1)BufferedReader BufferedReader br new BufferedReader(new InputStreamReader(System.in));//定義對象String[] strings br.readLine().split(" ");//讀取一行字符串&#xff0c;以空格為分隔轉化為字符串數組int n Integer.parseInt(strings[0])…

k8s分布式圖床(k8s,metricsapi,vue3+ts)

image-manage 圖像管理應用 圖像管理應用提供了一個方便管理圖片的平臺&#xff0c;支持單機和Kubernetes集群部署。請確保您至少擁有一個MySQL數據庫和一個Redis數據庫&#xff0c;以及一個至少為Kubernetes 1.29版本的集群&#xff08;如果選擇集群部署&#xff09;。 文檔…

PCL1.14.0安裝、使用教程

寫在前面 本文內容 本文是PCL1.14.0在Windows下的安裝、使用教程&#xff1b; PCL、Open3D其他版本的編譯和使用相關教程見 各個版本的Open3D、PCL的編譯、使用教程平臺/環境 windows11(windows10): visual studio 2022&#xff1b;cmake 3.22; VsCode轉載請注明出處&#xff…