繁体   English   中英

通过网络在C中接收文件

[英]Receive file in C over network

我正在尝试通过我的家庭网络接收文件,但没有取得多大成功。 我只能收到大约。 提供了此代码的 10 个字符,但我无法取得太大进展。 我在服务器端的发送功能工作正常,我 99% 确定这段代码中发生了一些我不理解的事情。 如果有人可以解释我做错了什么以及我应该做什么,那将不胜感激! 我知道应该添加正确的错误代码和检查,但只是为了保持一切整洁,我已经包含了繁重的代码。

//********************** CLIENT CODE BELOW(RECEIVE FILE)**
#include "StartConnection.h"

#include <pthread.h>
#include <errno.h>

#define FILENAME "/Users/name/Desktop/holaS.txt"
#define LENGTH (512)

// port number where to port in application
#define PORT_NUMBER (2005)

int clientSocket;
char buffer[LENGTH];
struct sockaddr_in serverAddr;
socklen_t addr_size;

void setup(){
    clientSocket = socket(PF_INET, SOCK_STREAM, 0); //socket create
    serverAddr.sin_family = AF_INET; // settings

    serverAddr.sin_port = htons(PORT_NUMBER); // port connection#
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");//ip localhost

    memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

    // bind
    addr_size = sizeof serverAddr;
    connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);

    /* FOR SENDING TEXT TO CONSOLE/REVEIVE
    recv(clientSocket, buffer, 1024, 0);
    Print the received message
    printf("Data received: %s",buffer);
    */

    rec_file(); // our entry
    close(clientSocket);
}

char rec_file() {
    recv(clientSocket, buffer, 512, 0);

    int file_size = 0;
    ssize_t len;

    int remain_data = 0;
    file_size = atoi(buffer); //512

    FILE *file;
    file = fopen(FILENAME,"ab+");

    if(file == NULL){
        printf("File Failed To Write");
    }

    remain_data = file_size;

    //
    while(((len = recv(clientSocket,buffer, buffer, 0)) >0) && (remain_data > 0)){
        fwrite(buffer, sizeof(char), len,file);
    }

    return 0;
}




//*********** SERVER CODE (SEND FILEBELOW*******************************************
#define PORT_NUMBER (2005)
int welcomeSocket, newSocket;
char buffer[512];
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;

void start_server(){
    welcomeSocket = socket(PF_INET, SOCK_STREAM, 0); // create socket

    serverAddr.sin_family = AF_INET; //type
    serverAddr.sin_port = htons(PORT_NUMBER);

    // localhost ip
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

    // bind address
    bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));

    // wait for connection max 5 connections
    if(listen(welcomeSocket,5)==0)
        printf("Listening\n");
    else
        printf("Error\n");

    addr_size = sizeof serverStorage; // accept <=5

    newSocket = accept(welcomeSocket, (struct sockaddr *&serverStorage, &addr_size);

    printf("\n OK PRINT MESSAGE");

    // char info[100];
    // scanf("%s",&info);
    // strcpy(buffer,info); // for writing text to client
    // send(newSocket,buffer,13,0);

    send_file(); // or entry function for our file send

    close(welcomeSocket);
}

void send_file(){
    /*
        char file_name[100];

        printf("Please Print Name of your File You Wish To Send");
        scanf("%s",&file_name);
    */

    FILE *f = fopen("/Users/name/Desktop/numbers.txt", "rb");

    fseek(f, 0, SEEK_END);

    long fsize = ftell(f);

    fseek(f, 0, SEEK_SET);  //same as rewind(f);

    char *string = malloc(fsize + 1);

    fread(string, fsize, 1, f);

    printf("\n Sending File");

    send(newSocket,string,13,0);

    fclose(f);

    printf("%s",string);

    string[fsize] = 0;
    free(string);
}

正如其他人已经指出的那样,这段代码存在一些明显的问题,例如:

while(((len = recv(clientSocket,buffer, buffer, 0)) >0) && (remain_data > 0)){
    fwrite(buffer, sizeof(char), len,file);
}

应该:

while(((len = recv(clientSocket,buffer, sizeof(buffer), 0)) >0) && (remain_data > 0)){
    remain_data -= len;
    fwrite(buffer, sizeof(char), len,file);
}

但是,整个客户端/服务器代码很笨拙。 您可能需要查看“Beej 的网络编程指南”之类的内容,并从那里给出的示例之一开始。

这是很难得到正确的。 有很多阅读手册页并参考了不同的代码来尝试使某些东西工作,不可否认,这是我第一次使用 C 套接字,我很高兴我很挣扎,因为我在这个过程中了解了套接字和其他东西。 所以发生的事情是双方都不正确。 使用“嘿,你好吗”之类的简单文本并发送 1 GB 文件是不同的,但在某种意义上是相同的。 需要使用具有正确逻辑的适当循环以及文件描述符,循环需要缓冲数据并读入发送套接字,并且您可以想象在接收端也需要在缓冲区中读取。 对我来说,真正赢得这场战斗的是这个 PDF(抱歉,我丢失了链接,但有名字,输入谷歌,你很可能会找到它)**“Mostafa Hassan Dahshan 博士计算机与信息科学学院沙特国王大学" *** 这给出了如何正确使用套接字的详细示例,您可以剖析并查看发生了什么。 出于对社区的强烈热爱,我不想发布我的代码,但这本书将帮助您得出相同的结论。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM