简体   繁体   中英

Reading in from a file X characters at a time in C

I'm attempting to write a program that allows me to read data from a file, then, using a data layer, sends it to another program that writes it to another file. The problem I am having is that I am limited to a frame size of 100 characters, including a 1 character header, and a 2 character CRC value that I will add in later. This means that I am reading in 97 characters at a time, then sending it off, but I'm not sure how to only read in that man characters than clear the char and start again. I will post the code I have, and any help is appreciated.

Send File

#include <stdio.h>
#define MAXFRAME  97
main(int argc, char* argv[]){
    char *frame;
    int len = 0;
    int c;
    dlinits("spirit.cba.csuohio.edu", 43520);
    frame = malloc(MAXFRAME);

    FILE *file = fopen(argv[1], "r");
    if (file == NULL)
        return NULL;

    while ((c = fgetc(file)) != EOF)
    {
        frame[len++] = (char) c;
    }


}

Receive File

#include <string.h>
char* dlrecv();

main(){
    char* test[100];
    dlinitr(43520);
    strcpy(test,dlrecv());

    printf("%s\n", test);



}

Data Layer

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#define BUFMAX 100

static int sk;
static struct sockaddr_in remote;
static struct sockaddr_in local;

dlinits(char* host, int port){//initialize sender

    struct hostent *hp;
    sk = socket(AF_INET, SOCK_DGRAM, 0);

    remote.sin_family = AF_INET;

    hp = gethostbyname(host);
    if (hp == NULL){
        printf("Can't find host name\n");
        exit(1);
    }

    bcopy(hp->h_addr,&remote.sin_addr.s_addr,hp->h_length);

    remote.sin_port = ntohs(port);
}

dlinitr(int port){//initialize receiver
    int rlen = sizeof(remote);
    int len = sizeof(local);
    char buf[BUFMAX];

    sk = socket(AF_INET,SOCK_DGRAM,0);

    local.sin_family = AF_INET;
    local.sin_addr.s_addr = INADDR_ANY;
    local.sin_port = htons(port);
    bind (sk, &local,sizeof(local));

    getsockname(sk,&local,&len);

}

dlsend(char* msg, int len){//send data

    printf("%s\n", msg);
    sendto(sk,msg,strlen(msg)+1,0,&remote,sizeof(remote));
} 

char* dlrecv(){//receive data
    char* msg = malloc(sizeof(char) * 100);

    recvfrom(sk,msg,BUFMAX,0,&remote,sizeof(remote));
    printf("%s\n", msg);
    return msg;
}

The core issue is the the data going out is not always 97 char (+3 overhead), yet the reading is always done 97+3 char at a time. Some approaches to solve this are:

1) Pad the outgoing so it is always a fixed number of char .

2) Receiver looks for a variable number of char to receive either with a lead length value or special terminator like \\0 .

For initial simplicity, suggest padding with \\0 .

After you get things going, use the 2nd method.


Other minor issues:

3) In appending a CRC, the values of the CRC range from 0 to 255 per each byte. This implies the sending/receiving method is binary and not text. Yet the file of data to send is opened in text mode "r". Need to be careful about potential EOL text/binary conversion issues. Eg using strlen(msg) . If msg is the entire lead byte + text + CRC, this will be a problem.

4) Avoid magic numbers. Rather self document them.

// dlinits("spirit.cba.csuohio.edu", 43520);
// dlinitr(43520);

// In some common header file
#define DATA_LAYER_PORT 43520
dlinits("spirit.cba.csuohio.edu", DATA_LAYER_PORT);
dlinitr(DATA_LAYER_PORT);

5) MAXFRAME and BUFMAX should not be independently defined.

// In some common header file
#define MAXFRAME 100
#define BUFMAX (MAXFRAME - 3)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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