我在C的一個問題,我沒有得到解決......通過UDP發送非文本文件不起作用
我寫了一個服務器端和一個在C客戶端應用程序
服務器應用程序讀取一個文件並將其分割成1024字節的塊,以便通過UDP將其發送到客戶端應用程序。
客戶端應用程序獲取這些塊,創建並寫入新文件。
如果輸入文件是應用程序正在工作的文本文件。
對於我目前正在研究的項目,我需要發送媒體文件(.mp3,.mp4,.ogg等)(是的,我需要爲此使用UDP)。如果我想發送像這樣的文件,它不起作用。
我的問題:
當我通過UDP套接字獲取數據,我得到1024個數據的每一次我收到一個消息 - 除了與上次包。應用程序將它通過UDP獲取的數據保存在char數組中。爲了獲得消息的長度,我檢查數組中的空字段。 (我嘗試了不同的方式,但沒有奏效......)對文本文件適用,但不適用於媒體文件。我怎樣才能做得更好? (大概不僅inefficent但糟糕的編碼風格,太...)
int l = 0; n = 0; for(l = 0; l<sizeof(buffer) ;l++){ if(buffer[l] != NULL){ n++; } }
什麼我必須做正確發送非文本數據?有通過UDP發送文件的更好的解決方案嗎?有人有一些建議嗎?
這裏是我對C-文件:
server.c
#include<arpa/inet.h>
#include<netinet/in.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<string.h>
#define PORT 9333
#define SERVER_IP "127.0.0.1"
#define BUFFER_SIZE 1024
FILE *input;
FILE *checkfile;
int n;
int count = 0;
struct sockaddr_in remote;
int s;
int main(){
unsigned char buffer[BUFFER_SIZE];
char check[100];
printf("Press ENTER to send file!\n");
fgets(check, 100, stdin);
input = fopen("input.txt", "r");
checkfile = fopen("checkfile.txt", "w");
if(input){
if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
fprintf(stderr, "Error getting a socket! \n");
exit(-1);
}
memset((char *) &remote, 0, sizeof(remote));
remote.sin_family = AF_INET;
remote.sin_port = htons(PORT);
if(inet_aton(SERVER_IP, &remote.sin_addr) == 0){
fprintf(stderr, "maybe no valid adress\n");
exit(1);
}
while(!feof(input)){
n = fread(buffer, 1, BUFFER_SIZE, input);
count += n;
printf("n = %d\n", n);
if(sendto(s, buffer, n, 0, &remote, sizeof(remote)) == -1){
fprintf(stderr, "error while sending data!\n");
exit(-1);
}
fwrite(buffer, 1, n, checkfile);
}
printf("%d bytes sent. \n", count);
}else{
printf("error while opening input file!");
}
printf("File sent!!\n");
close(s);
fclose(input);
return 0;
}
client.c:
#include<arpa/inet.h>
#include<netinet/in.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<string.h>
#define PORT 9333
#define BUFFER_SIZE 1024
int n;
FILE *output;
struct sockaddr_in local, remote;
int len_remote = sizeof(remote);
int s;
int count = 0;
int main(){
char buffer[BUFFER_SIZE];
output = fopen("output.txt", "w");
if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
fprintf(stderr, "Error getting a socket!\n");
exit(-1);
}
memset((char *) &remote, 0, sizeof(remote));
memset((char *) &local, 0, sizeof(remote));
local.sin_family = AF_INET;
local.sin_port = htons(PORT);
local.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(s, &local, sizeof(local)) == -1){
fprintf(stderr, "Cannot connect to service!\n");
exit(-1);
}
int flag = 1;
while(flag == 1){
memset(buffer, '\0', BUFFER_SIZE);
if(recvfrom(s, buffer, BUFFER_SIZE, 0, &remote, &len_remote) == -1){
fprintf(stderr, "fail while receiving data! \n");
exit(-1);
}
int l = 0;
n = 0;
for(l = 0; l<sizeof(buffer) ;l++){
if(buffer[l] != NULL){
n++;
}
}
count += n;
printf("n = %d\n", n);
fwrite(buffer, 1, n, output);
if(n<1024){
flag = 0;
}
}
printf("Got the file!\n");
close(s);
fclose(output);
return 0;
}
如果有人對我一些幫助/建議,那太好了。
最好的問候,
菲爾
創建2個數據文件,演示問題(一個工作,一個不),並將內容作爲每個十六進制轉儲發送 –
在發送實際文件發送文件屬性之前,請等待 –
告訴我您的操作系統?另請檢查文件大小(客戶端/服務器)兩側。如果Size相同,那麼在發送端更改傳輸文件的權限和屬性相同 –