通过UDP发送非文本文件不起作用

时间:2013-07-18 14:55:59

标签: c udp file-transfer

我在C中遇到问题我无法解决问题......

我用C编写了一个服务器和一个客户端应用程序。

服务器应用程序读取文件并将其切割成1024字节的块,以通过UDP将其发送到客户端应用程序。

客户端应用程序获取这些块,创建并写入新文件。

如果输入文件是文本文件,则应用程序正在运行。

对于我目前正在处理的项目,我还需要发送媒体文件(.mp3,.mp4,.ogg等)(是的,我需要使用UDP)。如果我想发送这样的文件,它就无法正常工作。

我的问题:

  • 当我通过UDP套接字获取数据时,每次收到消息时都会得到1024个数据 - 除了最后一个包。应用程序将通过UDP获取的数据保存在char数组中。为了获得消息的长度,我检查数组是否有空字段。 (我尝试了不同,但它没有工作......)适用于文本文件,但不适用于媒体文件。我怎么能做得更好? (可能不仅是无效的,而且编码风格也很糟糕......)

    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;

}

如果有人对我有一些帮助/建议,那就太好了。

致以最诚挚的问候,

菲尔

1 个答案:

答案 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,则可能需要创建一个基本协议,其中包含一些信息(数据包的数量,数据包中的字节数等)。