0

我在 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 文件:

服务器.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;
}

客户端.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;

}

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

此致,

菲尔

4

1 回答 1

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,您可能想要创建一个包含一些信息(数据包数、数据包中的字节数等)的基本协议。

于 2013-07-18T15:13:18.670 回答