吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux開發_文件發送與接收

DS小龍哥-嵌入式技術 ? 2022-09-17 15:23 ? 次閱讀

【摘要】 介紹文件發送、文件接收、線處理服務器接收、獲取天氣預報等知識點。

任務1:網絡編程

1.1 練習題說明

1.?實現TCP服務器與TCP客戶端之間的基本通信,收發數據 (按照上課的思路流程看函數文檔)

2.?實現TCP服務器與TCP客戶端之間的文件傳輸。(單個文件傳輸)

驗證方式: (1) 同一臺電腦演示 (2)同桌之間演示

考慮的問題:

(1)?網絡的傳輸環境,考慮應答問題

(2)?數據丟包之后如何處理? 可以重發

(3)?超時處理

(4)?服務器與客戶端之間連接斷開處理。(客戶端和服務器兩邊都需要重新連接)

文件傳輸可以在廣告機中使用。

(5)?每個數據的單位: 分包發送

(擴展要求): 顯示接收進度百分比,顯示接收的文件名稱,推薦: 定義結構體(使用數據結構)

3.?(擴展)實現TCP服務器與TCP客戶端之間的目錄傳輸(一級目錄)。

4.?(擴展)實現網絡聊天室(模仿QQ群發送消息的效果)

(1)?加入進去的成員都是客戶端

(2)?服務器負責給各個客戶端轉發消

??一般情況下,推薦最大每次傳輸的字節數不超過1024字節。

(1)文件發送客戶端

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/*
TCP客戶端:
1. sockt創建套接字
2. 連接服務器
*/
int socket_cfd; /*保存客戶端套接字*/
int main(int argc,char **argv)
{
	if(argc!=4)
	{
		printf("./server <192.168.xx.xx 服務器的IP地址> <服務器端口號> <文件名稱>\n");
		exit(-1);
	}
	
	FILE *file=fopen(argv[3],"wb");
	if(file==NULL)
	{
		printf("文件創建失敗!");
		exit(0);
	}
	
	int err; //存放返回值狀態
	/*1. 創建套接字*/
	socket_cfd=socket(AF_INET,SOCK_STREAM,0);
	if(socket_cfd<0)
	{
		printf("服務器端創建失敗!\n");
		exit(-1);
	}
	
	/*2.連接服務器*/
	struct sockaddr_in ServerAddr;
	ServerAddr.sin_family=AF_INET; //IPV4協議
	ServerAddr.sin_port=htons(atoi(argv[2]));      //服務器的端口號 最大值65535
	ServerAddr.sin_addr.s_addr=inet_addr(argv[1]); //IP地址賦值
	
	err=connect(socket_cfd,(const struct sockaddr *)&ServerAddr,sizeof(struct sockaddr));
	if(err!=0)
	{
		printf("服務器連接失敗!\n");
		exit(-1);
	}
	
	/*3. 收發數據: 接收服務器發送的數據*/
	char rx_buff[100];
	fd_set readfds; //存放讀事件
	int data;
	int ack=666;
	while(1)
	{
		FD_ZERO(&readfds); //清空文件描述符
		FD_SET(socket_cfd,&readfds); //添加需要監控的文件描述符 
		data=select(socket_cfd+1,&readfds,NULL,NULL,NULL);
		if(data>0)
		{
			err=read(socket_cfd,rx_buff,100);
			if(err==0 && data==1)
			{
				printf("服務器已經與客戶端斷開連接!\n");
				break;
			}
			fwrite(rx_buff,1,err,file);//寫入數據
			printf("客戶端成功接收%d個字節\n",err);
			
			write(socket_cfd,&ack,4); //發送應答信號。
		}
	}
	close(socket_cfd);
	fclose(file);
	return 0;
}

(2)文件發送客戶端

#include 
#include 
#include 
#include 
#include 
#include 

/*
TCP服務器:
1. sockt創建套接字
2. bind綁定端口
3. 設置監聽的數量
4. 等待客戶端連接
*/
int socket_sfd; /*保存了服務器端的套接字*/
int socket_cfd; /*已經連接成功的客戶端套接字*/

/*
服務器是發送端
*/
int main(int argc,char **argv)
{
	if(argc!=4)
	{
		printf("./server <192.168.xx.xx 本地IP地址> <服務器端口號> \n");
		exit(-1);
	}
	
	FILE *file=fopen(argv[3],"rb");
	if(file==NULL)
	{
		printf("文件打開失敗!\n");
		exit(0);
	}
	
	int err; //存放返回值狀態
	/*1. 創建套接字*/
	socket_sfd=socket(AF_INET,SOCK_STREAM,0);
	if(socket_sfd<0)
	{
		printf("服務器端創建失敗!\n");
		exit(-1);
	}
	
	/*2. 綁定端口*/
	struct sockaddr_in ServerAddr;
	ServerAddr.sin_family=AF_INET; //IPV4協議
	ServerAddr.sin_port=htons(atoi(argv[2]));      //服務器的端口號 最大值65535
	ServerAddr.sin_addr.s_addr=inet_addr(argv[1]); //IP地址賦值
	err=bind(socket_sfd,(const struct sockaddr *)&ServerAddr,sizeof(struct sockaddr));
	if(err!=0)
	{
		printf("服務器端 端口綁定失敗!\n");
		exit(-1);
	}
	
	/*3. 設置監聽的數量*/
	listen(socket_sfd,10);
	
	/*4. 等待客戶端連接*/
	struct sockaddr_in ClientAddr; //存放已經連接成功客戶端信息
	socklen_t addrlen=sizeof(struct sockaddr);    //客戶端的地址長度
	socket_cfd=accept(socket_sfd,(struct sockaddr *)&ClientAddr,&addrlen);
	if(socket_cfd<0)
	{
		printf("服務器端,連接客戶端失敗!\r\n");
		exit(-1);
	}
	
	/*打印一些客戶端的信息*/
	printf("成功連接的客戶端端口號:%d\n",ntohs(ClientAddr.sin_port));
	printf("成功連接的客戶端IP地址:%s\n",inet_ntoa(ClientAddr.sin_addr));
	
	/*5. 收發數據 :服務器給客戶端發送10個字節的數據*/
	char tx_buff[100];
	int len;
	int ack;
	while(1)
	{
		len=fread(tx_buff,1,100,file);
		printf("服務器成功發送:%d 字節\r\n",len);
		err=write(socket_cfd,tx_buff,len);
		while(1)
		{
			err=read(socket_cfd,&ack,4);  //等待客戶端的應答
			if(err>0&&ack==666)
			{
				break;
			}
		}	
		if(len!=100)break;
	}
	close(socket_sfd);
	fclose(file);
	return 0;
}

文件名稱>

任務2:線程編程

#include

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

void *(*start_routine) (void *), void *arg);

Compile and link with -pthread.

-lpthread

理解: 一個線程就是一個while(1)。

[root@wbyq linux-share-dir]# gcc app.c

/tmp/cccOs4TK.o: In function `main':

app.c:(.text+0x69): undefined reference to `pthread_create'

app.c:(.text+0x8d): undefined reference to `pthread_create'

collect2: ld 返回 1

[root@wbyq linux-share-dir]# gcc app.c -lpthread

練習:

1.?學習線程的基本使用

2.?實現一個服務器實現多個客戶端的連接,實現通信。

思路: 一個客戶端就是一個獨立的線程。

3.?擴展練習: 實現服務器同時對多個客戶端進行文件發送。

(1)?服務器連接上一個客戶端就創建一個線程。

(2)?線程的函數需要寫幾個? 1個

1個函數需要考慮的問題: 函數的可重入性能!

需要考慮到資源搶占! 使用信號量!

1.?CRC16、CRC32校驗、

2.?和校驗 ”abcd <校驗和>” -->和

3.?異或校驗。 (1) 文件加密解碼

(2) 不添加三個變量,將兩個變量的值交換

int a=666; int b=888;

4.?MD5值校驗。

客戶端:

#include 
#include           /* See NOTES */
#include 
#include    //使用大小端轉換函數. find /
#include 
/*服務器端口號定義*/
#define P_host 8080

//  ./app   192.168.18.3
/*TCP客戶端代碼*/
int main(int argc,char *argv[])
{
	  if(argc!=2)
	  {
	  	  printf("參數錯誤:./app <服務器IP地址>\n");
	  		return -1;
	  }
	 int clientfd;
	 struct sockaddr_in server_address;     //存放服務器的IP地址信息
	 memset(&server_address,0,sizeof(struct sockaddr_in)); //初始化內存空間
	 server_address.sin_family=AF_INET;            //IPV4協議
	 server_address.sin_port=htons(P_host);        //端口號賦值
	 server_address.sin_addr.s_addr=inet_addr(argv[1]);    //本地IP地址
	 /*1 .創建套接字*/
    clientfd=socket(AF_INET,SOCK_STREAM,0);
   if(clientfd<0)
   	{
   	    printf("客戶端網絡套接字創建失敗!\n");	
   	    return -1;
   	}
   	
   	/*2. 連接服務器*/
   	if(connect(clientfd,(const struct sockaddr *)&server_address,sizeof(struct sockaddr))!=0)
   	{
   		  printf("客戶端連接服務器失敗!\n");	
   	    return -1; 	
   	}
   	char buff[1024];
   	
   	while(1)
   	{
   	    gets(buff);
   	    write(clientfd,buff,strlen(buff)); 
   	}
		return 0;
}

服務器:

#include 
#include           /* See NOTES */
#include 
#include    //使用大小端轉換函數
#include 
#include 
#include 
#include 
#include 
#include 
//函數聲明
void *start_routine_1(void *dev);
void *start_routine_2(void *dev);

typedef void *(*start_routine) (void *);
start_routine fun[]={start_routine_1,start_routine_2};
pthread_t thread_id[2];                //存放線程的標識符
int clientfd[2];                       //保存TCP客戶端的網絡套接字
struct sockaddr_in client_address[2];  //存放客戶端的信息
socklen_t address_len[2];              //存放客戶端結構體信息的長度
/*服務器端口號定義*/
#define P_host 8080

/*TCP服務器代碼*/
int main(int argc,char *argv[])
{
	 int socketfd;
	 struct sockaddr_in server_address;     //存放服務器的IP地址信息
	 memset(&server_address,0,sizeof(struct sockaddr_in)); //初始化內存空間
	 memset(client_address,0,sizeof(struct sockaddr_in)*2); //初始化內存空間
	 server_address.sin_family=PF_INET;            //IPV4協議
	 server_address.sin_port=htons(P_host);        //端口號賦值
	 server_address.sin_addr.s_addr=INADDR_ANY;    //本地IP地址
  /*1 .創建套接字*/
   socketfd=socket(PF_INET,SOCK_STREAM,0);
   if(socketfd<0)
   	{
   	    printf("服務器網絡套接字創建失敗!\n");	
   	    return -1;
   	}
      	 
   /*2. 綁定端口,創建服務器*/
   if(bind(socketfd,(const struct sockaddr *)&server_address,sizeof(struct sockaddr))!=0)
   	{
   	    printf("服務器綁定端口失敗!\n");	
   	    return -1; 	
   	}
   
   /*3. 設監聽的端口數量*/
   if(listen(socketfd,10)!=0)
   	{
   	   printf("服務器端口監聽失敗!\n");	
   	   return -1;	 
   	}
   
    int i;
    
    for(i=0;i<2;i++)
   	{
   		 address_len[i]=sizeof(struct sockaddr);  //計算結構體大小 20 
   	  /*4. 等待客戶端連接*/
	    if((clientfd[i]=accept(socketfd,(struct sockaddr *)&client_address[i],&address_len[i]))<0)
	   	{
	   	   	printf("等待客戶端連接失敗!\n");	
	   	    break;	
	   	} 
	    
	    //創建線程
	   	if(pthread_create(&thread_id[i],NULL,fun[i],NULL)!=0)
		{
		   printf("線程_%d_創建失敗!\n",i);		
		} 	
   	}
   	
   	while(1)
   	{
   	    	
   	}
     	
   //阻塞方式等待線程的結束
	pthread_join(thread_id[0],NULL);
	pthread_join(thread_id[1],NULL);
	return 0;	
}
//線程1
void *start_routine_1(void *dev)
{
	 while(1)
	 {
	 	  printf("TCP客戶端1連接!\n");
	 	  sleep(2);
	 }
	 //終止線程
	 pthread_exit(NULL);
}
//線程2
void *start_routine_2(void *dev)
{
	while(1)
	{
	 	  printf("TCP客戶端2連接!\n");
	 	  sleep(2);
	}
	 //終止線程
	 pthread_exit(NULL);
}

任務3:使用的網絡服務器接口

C語言:面向過程 、 面向對象

1.?車牌號識別

2.?二維碼生成

3.?獲取北京時間

獲取接口的網址:http://www.k780.com/

1.?調用網絡的接口的方式: (天氣預報)

curl http://api.k780.com:88/?app=weather.future'&'weaid=南昌

'&&'appkey=10003'&'sign=b59bc3ef6191eb9f747dd4e83c99f2a4'&'format=json >123.txt

注意: &是特殊的符號,需要使用單引號或者雙引號括起來。

Curl: 命令行的瀏覽器。

2.?調用二維碼生成的接口

curl http://api.k780.com:88/?app=qr.get'&'data=www.wanbangee.com'&'level=L'&'size=6 >123.png

?? 練習:

1.?天氣預報查詢

查詢的格式: ./app <城市的中文名稱>

poYBAGMlPamARKUnAAA4mjEWJsA386.png

2.?獲取北京標準時間,顯示出來

pYYBAGMlPamAcAvwAAAMsIAQj18578.png

3.?二維碼生成創建 運行格式: ./app <生成的二維碼內容>

生成之后直接顯示在屏幕上??梢允褂胑og命令

4.?車牌號的識別

5.?調用百度地圖API接口 http://lbsyun.baidu.com/index.php?title=uri/api/web

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 服務器
    +關注

    關注

    12

    文章

    9308

    瀏覽量

    86072
  • TCP
    TCP
    +關注

    關注

    8

    文章

    1378

    瀏覽量

    79309
  • 文件
    +關注

    關注

    1

    文章

    570

    瀏覽量

    24823
收藏 人收藏

    評論

    相關推薦

    Linux文件查找

    Linux文件查找 1.find查找概述 為什么要有文件查找,因為很多時候我們可能會忘了某個文件所在的位置,此時就需要通過find來查找。 find命令可以根據不同的條件來進行查找
    的頭像 發表于 12-03 17:09 ?352次閱讀

    socket 發送接收數據方法

    1. Socket 基本概念 在網絡編程中,socket 是一個通信端點。它允許程序發送接收數據。根據通信協議的不同,socket 可以分為以下幾種類型: 流式 socket
    的頭像 發表于 11-12 14:07 ?683次閱讀

    Linux開發怎么學?

    Linux開發怎么學? 學習 Linux 是一個循序漸進、持續不斷的過程。我們可以從以下幾個方面開始 1.了解 Linux 的歷史和發展: 了解
    發表于 10-10 14:34

    Linux文件系統的掛載過程

    Linux文件系統(rootfs)是Linux系統中所有其他文件系統和目錄的起點,它是內核啟動時掛載的第一個文件系統。
    的頭像 發表于 10-05 16:50 ?518次閱讀

    如何構建Linux文件系統

    構建Linux文件系統是一個涉及多個步驟和概念的過程,它對于Linux系統的啟動和運行至關重要。
    的頭像 發表于 10-05 16:47 ?352次閱讀

    嵌入式linux開發的基本步驟有哪些?

    嵌入式Linux開發是一個復雜的過程,涉及到硬件選擇、操作系統移植、驅動開發、應用程序開發等多個方面。以下是嵌入式Linux
    的頭像 發表于 09-02 09:11 ?635次閱讀

    嵌入式linux開發板芯片的工作原理

    嵌入式Linux開發板是一種基于Linux操作系統的嵌入式系統開發平臺,它廣泛應用于工業控制、智能家居、智能交通、醫療設備等領域。 嵌入式Linux
    的頭像 發表于 09-02 09:07 ?475次閱讀

    linux開發板與樹莓派的區別

    定義和用途 Linux開發板:Linux開發板是一種基于Linux操作系統的嵌入式開發板,通常用
    的頭像 發表于 08-30 15:34 ?1141次閱讀

    linux開發板和單片機開發的區別

    硬件架構 Linux開發板和單片機開發在硬件架構上有很大的區別。Linux開發板通常基于ARM、x86或其他處理器架構,具有較高的處理能力和
    的頭像 發表于 08-30 15:30 ?1255次閱讀

    Linux 驅動開發與應用開發,你知道多少?

    一、Linux驅動開發與應用開發的區別開發層次不同:Linux驅動開發主要是針對硬件設備進行編程
    的頭像 發表于 08-30 12:16 ?929次閱讀
    <b class='flag-5'>Linux</b> 驅動<b class='flag-5'>開發</b>與應用<b class='flag-5'>開發</b>,你知道多少?

    使用超聲波發送器和接收器構建高性能NDT系統

    電子發燒友網站提供《使用超聲波發送器和接收器構建高性能NDT系統.pdf》資料免費下載
    發表于 08-28 11:00 ?0次下載
    使用超聲波<b class='flag-5'>發送</b>器和<b class='flag-5'>接收</b>器構建高性能NDT系統

    如何更改Linux文件系統終端顯示顏色

    自己制作的簡單 Linux 文件系統,你會發現終端顯示為黑白色,很不好看
    的頭像 發表于 08-12 17:29 ?718次閱讀
    如何更改<b class='flag-5'>Linux</b><b class='flag-5'>文件</b>系統終端顯示顏色

    如何通過串口發送文件?

    想使用串口在兩臺電腦之間傳送任意文件,比如一個圖片文件,以文本或者二進制的方式讀取數據,然后通過串口發送出去,接收端將這些數據接收,然后以同
    發表于 07-31 12:51

    使用ESP32-S3開發板http post請求發送SD卡上的大文件,如何循環邊讀取文件邊分塊發送文件呢?

    您和,我準備使用ESP32-S3開發板http post請求發送SD卡上的大文件,但是使用esp_http_client_set_post_field的buffer太小,內存不能一次性申請太大,請問
    發表于 06-06 06:19

    TSMaster 序列發送模塊在汽車開發測試中的應用

    眾所周知,序列發送模塊可以不需要腳本代碼實現測試中特定控制報文序列的發送,該模塊多用于循環順序控制的測試案例中。序列發送模塊的常用場景,主要是針對一些新開發的產品需要通過該模塊來驗證產
    的頭像 發表于 02-19 14:00 ?745次閱讀
    TSMaster 序列<b class='flag-5'>發送</b>模塊在汽車<b class='flag-5'>開發</b>測試中的應用
    516棋牌游戏中心| 百家乐扑克投注赢钱法| 聚宝盆百家乐官网的玩法技巧和规则| 百家乐官网大转轮真人视讯| 百家乐官网庄闲和各| 新宝百家乐官网网址| 扎兰屯市| 百家乐官网最稳妥的打法| 百家乐官网开发软件| 百乐坊百家乐官网娱乐城| 怎样打百家乐官网的玩法技巧和规则 | 平度市| 百家乐官网投注技巧建议| 澳门百家乐官网规则视频| 真人百家乐官网蓝盾娱乐网| 真人百家乐官网网络游戏信誉怎么样 | 大发888官方网| 大发888送彩金| bet365体育投注心得| 新巴尔虎右旗| 百家乐官网9点| 百家乐官网是多少个庄闲| 博彩百家乐官网最新优惠| 金沙百家乐娱乐城场| 百家乐微笑玩| 澳门百家乐上下限| 玩百家乐技巧看| 澳博国际娱乐| 赌百家乐官网心里技巧| 星期8百家乐官网娱乐城| 百家乐佛牌| 棋牌室转让| 视频百家乐官网平台出租| 百家乐官网九| 百家乐投法| 足球博彩网| 百家乐官网赌场技巧论坛| 注册百家乐送彩金 | 万豪国际| 百家乐官网衬衣| 百家乐做庄家必赢诀窍|