[英]udp socket programming file transfer
服務器端代碼......
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#define BUFLEN 503
#define PORT 8885
void die(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_me, si_other;
int s, i,j, slen = sizeof(si_other) , recv_len;
char buf[BUFLEN];
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
die("socket");
}
memset((char *) &si_me, '1', sizeof(si_me));
//printf("%d",si_me);
si_me.sin_family = AF_INET;
si_me.sin_port = PORT;
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
{
die("bind");
}
//memset(buf,0,503);
char fname[20];
FILE *fp;
recv_len = recvfrom(s, buf, 20, 0, (struct sockaddr *) &si_other, &slen);
char fna[100];
memset(buf,0,503);
recv_len = recvfrom(s, buf, 20, 0, (struct sockaddr *) &si_other, &slen);
strcpy(fna,buf);
//printf("%c\n",fna);
int len= strlen(fna);
printf("%d",len);
unsigned long mm = atoi(buf);
//printf("mm value: %ld\n",mm);
fp=fopen(fna,"wb");
int itr=1;
memset(buf,0,503);
while(itr*503<mm)
{
if ((recv_len = recvfrom(s, buf, 503, 0, (struct sockaddr *)&si_other, &slen)) == -1)
{
die("recvfrom()");
}
fwrite(buf,503, 1, fp);
memset(buf,0,503);
//printf("Loop no: %d",i)
//for(i=0;i<=itr;i++);
itr++;
}
//printf("Loop no: %d\n",i);
printf("%d",(mm%503));
recv_len = recvfrom(s, buf, (mm%503), 0, (struct sockaddr *) &si_other, &slen);
fwrite(buf,(mm%503), 1, fp);
memset(buf,0,503);
fclose(fp);
close(s);
return 0;
}
客戶端代碼........
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#define SERVER "127.0.0.1"
#define BUFLEN 503
#define PORT 8885
void die(char *s)
{
perror(s);
exit(1);
}
unsigned long fsize(char* file)
{
//String bbb=file;
FILE * f = fopen(file, "r");
fseek(f, 0, SEEK_END);
unsigned long len = (unsigned long)ftell(f);
printf("Total size: %d \n",len);
fclose(f);
return len;
}
int main(void)
{
struct sockaddr_in si_other;
int s, i, slen=sizeof(si_other);
char buf[BUFLEN];
char message[BUFLEN];
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
die("socket");
}
memset((char *) &si_other, '1', sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = PORT;
//printf("Htons= %d \n",htons(PORT));
if (inet_aton(SERVER , &si_other.sin_addr) == 0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
//memset(message,0,503);
char fname[20];
printf("Enter Filename with extension: ");
scanf("%s",&fname);
sendto(s, fname, 20 , 0 , (struct sockaddr *) &si_other, slen);
memset(message,0,503);
unsigned long siz = fsize(fname);
printf("siz: %ld\n",siz);
char str[10];
sprintf(str, "%d", siz);
int send1=sendto(s, str, 20 , 0 , (struct sockaddr *) &si_other, slen);
printf("value of send1= %d",send1);
FILE *f;
f=fopen(fname,"rb");
memset(message,0,503);
fread(message, 503,1,f);
int itr =1;
while(itr*503<siz){
if (sendto(s, message, 503 , 0 , (struct sockaddr *) &si_other, slen)==-1)
{
die("sendto()");
}
memset(message,0,503);
fread(message, 503,1,f);
itr++;
}
fread(message, (siz % 503),1,f);
int send2=sendto(s, message, (siz % 503) , 0 , (struct sockaddr *) &si_other, slen);
printf("\n value of send 2= %d",send2);
memset(message,0,503);
fclose(f);
close(s);
return 0;
}
這是 UDP 套接字編程中的圖像、視頻、文本文件等文件傳輸代碼。(從客戶端到服務器端文件夾)。
誰能向我解釋為什么兩邊都使用WHILE
循環,它的目的是什么? 此外,一個問題是使用此程序文件從客戶端正確發送到服務器,但到達服務器端后文件名正在更改。
unsigned long len = (unsigned long)ftell(f);
printf("Total size: %d \n",len);
經過測試,我發現服務器端更改的文件名設置為客戶端len
變量中文件指針的當前位置。( len
值與服務器端的變量mm
和變量“ siz
”相同在客戶端。
例如:
如果我從服務器端發送“Wallpaper.png”,它將到達服務器端並且文件以名稱“164101”保存。 但圖像顯示正確。
為什么 memset 被使用了這么多次?? 它的實際用途是什么??
您的客戶端和服務器使用相同的文件傳輸協議,定義如下:
在服務器端,您正在處理應該存儲文件名fname
變量和應該存儲文件長度fna
變量。 您可能應該將后者重命名為flen
就像在以下代碼段中一樣:
...
char fname[20]; // variable to store file name
FILE *fp;
recv_len = recvfrom(s, buf, 20, 0, (struct sockaddr *) &si_other, &slen);
strcpy(fname, buf); // got 20 bytes in buf, copy to fname : this is the file name
printf("File name : %s\n", fname);
char flen[20];
memset(buf,0,503); // reset NULL bytes to buf
recv_len = recvfrom(s, buf, 20, 0, (struct sockaddr *) &si_other, &slen);
strcpy(flen, buf); // got 20 bytes, copy to flen : this is the file length (as a string)
printf("Length as string : %s\n", flen);
printf("Length as integer : %d\n", atoi(flen));
unsigned long mm = atoi(buf); // convert file length as a string to an integer variable
printf("mm value: %ld\n",mm);
fp=fopen(fname,"wb"); // use the proper variable as the file name
int itr=1;
...
希望這可以幫助!
while
循環用於將文件拆分為適合 UDP 數據報的較小塊,這些塊具有有限的大小。 與 TCP 不同,UDP 不處理這些細節,因此您必須自己實現所有這些。
最終,您還必須實現超時和重傳、重復數據報檢測以及可能的某種形式的擁塞控制。 編寫一個好的文件傳輸協議來擊敗基於 UDP 的基於 TCP 的解決方案是非常困難的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.