2013-07-18 2 views
0

У меня есть проблемы в C, где я не получить к решению ...Отправка нетекстовых файлов через UDP не работает

Я написал и поддерживаемый сервер клиентского приложения в C .

Сервер-приложение считывает файл и разрезает его на куски 1024 байта, чтобы отправить его через UDP в клиентское приложение.

Клиент-приложение получает эти куски, создает и записывает новый файл.

Если входной файл является текстовым файлом, приложения работают.

Для проекта, в котором я сейчас работаю, мне нужно также отправить медиафайлы (.mp3, .mp4, .ogg и т. Д.) (Да, для этого мне нужно использовать UDP). Если я хочу отправить такие файлы, они не работают.

Мои проблемы:

  • Когда я получаю данные через UDP-сокет я получаю 1024 данных каждый раз, когда я получаю сообщение - за исключением последнего пакета. Приложение сохраняет данные, которые он получает через UDP в массиве символов. Чтобы получить длину сообщения, я проверяю массив на пустые поля. (Я пробовал разные, но это не сработало ...) Прекрасно работает для текстовых файлов, но не для медиа-файлов. Как я могу сделать это лучше? (Вероятно, не только 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; 

} 

Если кто-то имеет какие-то помощь/советы для меня, это было бы прекрасно.

С наилучшими пожеланиями,

Phil

+0

создать 2 файла данных, которые демонстрируют проблему (тот, который работает, тот, который этого не делает), и разместить содержимое в виде шестнадцатеричного дампа каждого –

+0

Перед отправкой фактического файла отправить свойства файлов, подождите –

+0

дайте мне знать вашу операционную систему ? Также проверьте размер файла (на клиенте/сервере) с обеих сторон. если размер тот же, что и разрешение на изменение и свойства переданного файла одинаково на стороне отправителя –

ответ

0

От client.c:

int nbrecv = 0;  
while(flag == 1){ 

    memset(buffer, '\0', BUFFER_SIZE); 

    if((nbrecv = recvfrom(s, buffer, BUFFER_SIZE, 0, &remote, &len_remote)) == -1){ 
     fprintf(stderr, "fail while receiving data! \n"); 
     exit(-1); 
    } 

    count += nbrecv; 
    printf("n = %d\n", nbrecv); 

    fwrite(buffer, 1, nbrecv, output); 

    if(nbrecv<1024){ 
     flag = 0; 
    } 

} 

recvfrom() возвращает количество принятых байт, используйте его.

Помните, что UDP не имеет гарантий (пакеты не переупорядочены или что-то еще). Если вы используете UDP, вы можете создать базовый протокол, который будет содержать некоторую информацию (номер пакета, количество байтов в пакете и т. Д.).

+0

Большое спасибо, что решило проблему. –