Receiving rtp packets and writing them into binary file - c

I am receiving rtp packets from a server that I have to write them into a .mp3 file and I have a few questions on how to complete this task. The last packet I am receiving contains an "END" string.
My code is the following:
int size = 524;
char rtp[size];
FILE *f;
f=fopen("music.mp3","wb");
while(strcmp((char *)rtp, "END")){
recvfromserver(socket,rtp,sizeof(rtp));
fwrite(rtp, sizeof(rtp), 1, f);
}
fclose(f);
My questions are the following:
Is char the correct type for this type of packet? I have to write the file in binary so I do not know if I am doing it right.
How do I write into the file without writing the header of the rap packet? This header is 12B and I should remove it before doing fwrite(), but I do not know if I have to use char or int.
Thanks a lot in advance!

Yes char* is the right data type for your need. In fact I would be more inclined to use unsigned char*
I have done the following modification to your code:-
Initialized the rtp buffer - Think of a case the stack memory where rtp is defined contains "END\0XXX" ? Your write loop will never execute. Always a good practice to initialize variables form stack
Since you are saying you don't need to write the first 12 bytes from rtp, I have advanced the byte pointer by 12 in fwrite
Adjusted the 2nd param of fwrite by 12 bytes to ensure you are not writing form beyond 524 bytes of rtp
You might have to think about what you get from recvfromserver Is that a null terminated character array?
Modified code:-
int size = 524;
char rtp[size] = {0}; //Initialized rtp
FILE *f;
f=fopen("music.mp3","wb");
while(strcmp((char *)rtp, "END")){
recvfromserver(socket,rtp,sizeof(rtp));
fwrite(rtp+12, sizeof(rtp)-12, 1, f); //adjusted for 12 bytes of header
}
fclose(f);

Related

How to read in a binary file and store the data at a pointer in C

So I am working on a project and I am failing to put all the pieces together to make this work. We need to read in the header of a binary file and store them at the specified pointer.
the function I am working in:
int read_header (FILE *file, elf_hdr_t *hdr);
I understand how to pass the info to the function but I am failing to understand how to read in to the specified pointer. I have been trying to find information on this all day but cant really figure out my starting point... Thanks for any direction you can provide.
My code so far:
int read_header (FILE *file, elf_hdr_t *hdr)
{
int read;
read = fread(hdr, 1, sizeof(hdr), file);
fclose(file);
}
I want to know if I am doing what I am trying here, basically want to read in one byte at a time to the specified pointer.
Since hdr is a pointer, sizeof(hdr) will just be the size of a pointer. You want sizeof(*hdr) or sizeof(elf_hdr_t) to get the size of the elf header struct that the pointer points at...
please re-read the MAN page for fread()
These two parameters: 1, sizeof(hdr), are saying to read in sizeof(hdr) bytes, not to read in 1 byte

Should POSIX `read()`'s `buf` be `signed` or `unsigned`? Does it even matter?

POSIX read function is defined as ssize_t read(int fd, void *buf, size_t count);, taking its buf argument as void*.
Does it matter if the actual buffer passed in is an array of chars or unsigned chars? If so, which one should I use? I googled and read the man, but even the type of the buffer isn't mentioned, let alone its signedness.
The reason for having the declared type void * is that you can read pretty much any type. You can read a char. You can read an unsigned char. You can read an int, if what you wrote to the file earlier was also an int. You can read a struct div_t, if that is what was written to the file.
Pick whatever type was written to the file, or if you're reading arbitrary bytes, whichever type works best for your later processing.
Does it matter if the actual buffer passed in is an array of chars or unsigned chars?
No. Moreover, those are not your only choices. The buffer to which the second argument points can have any object type. It's reasonably common for it to point to either a char array or an unsigned char array, but not so uncommon for it to point to an array of some (other) integer type, or to an object of structure type, or to something else.
The primary objective is to interpret the data received according to the data type intended by the sender, and that requires that you either know in advance or be able to determine from the data what type is intended. In other words, sender and receiver need to agree on some kind of communication protocol.
The simplest possible protocol is an undifferentiated stream of bytes; for that, an unsigned char array is the most appropriate choice. Some other choices are better suited to other protocols.
"read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf."
Read() will store bytes from your file descriptor (be a file, a socket or whatever).
The bytes will be stored at your pointer address, whatever its type. The way your program understand those bytes depends on how you declared it.
so for example, same byte 0xFF may be interpreted as 255 or -1 by your program upon buf declaration
From http://pubs.opengroup.org/onlinepubs/009695399/functions/read.html:
The read() function shall attempt to read nbyte bytes from the file associated with the open file descriptor, fildes, into the buffer pointed to by buf.
It is up to you how to interpret the bytes. Whether your buf is an array of char or unsigned char does not make a difference to the workings of read. Only you decide how to interpret the data. If the data contained in the file are not char, you might end up misinterpreting its contents if you treat them as an array of char. That again depends on your platform.
It is not necessarily correct to interpret the data as an array of unsigned char either. The data in the file might be an array of floats or an array of struct containing mixed data types.
Bottom line - you need to read the data into the appropriate object type in memory. To do that, you have to know what is saved in the file.

Will file pointer move with the change of file position?

When reading K&R, I became interested in how the file position is determined. By file position, I mean where in the file the stream is currently reading or writing. I think it must have something to do with the file pointer, or the piece of data it's pointing to. So I checked stack overflow, and find the following answer:
Does fread move the file pointer?
The answer indicates that file pointer will change with the change of file position. This makes me very confused, because in my understanding, a file pointer for a certain file should always point to the same address, where information about this file is stored. So I wrote a small piece of code, trying to find the answer:
#include<stdio.h>
int main(void)
{
char s[1000];
FILE *fp,*fp1,*fp2;
fp = fopen("input","r");
fp1 = fp; /* File poiter before fread */
fread(s,sizeof(char),100,fp);
fp2 = fp; /* File pointer after fread */
printf("%d\n",(fp1 == fp2) ? 1 : -1);
}
It gives the output 1, which I believe indicates that the file pointer actually doesn't move and is still pointing to the same address. I have also changed the fread line to be a fseek, which gave the same output. So does file pointer move with the change of file position, or where am I wrong in the verifying process?
Thanks!
I think you are confusing the general concept of pointers in C, vs. the nomenclature of a "file pointer". FILE is just a structure that contains most of the "housekeeping" attributes that the C stdio runtime library needs to interact with when using the stdio functions such as, fopen(), fread(), etc. Here is an example of the structure:
typedef struct {
char *fpos; /* Current position of file pointer (absolute address) */
void *base; /* Pointer to the base of the file */
unsigned short handle; /* File handle */
short flags; /* Flags (see FileFlags) */
short unget; /* 1-byte buffer for ungetc (b15=1 if non-empty) */
unsigned long alloc; /* Number of currently allocated bytes for the file */
unsigned short buffincrement; /* Number of bytes allocated at once */
} FILE;
Note that this may be somewhat platform-dependent, so don't take it as gospel. So when you call fopen(), the underlying library function interacts with the O/S's file system APIs and caches relevant information about the file, buffer allocation, etc, in this structure. The fopen() function allocates memory for this structure, and then returns the address of that memory back to the caller in the form of a C Pointer.
Assigning the pointers values to another pointer has no effect on the attributes inside the FILE structure. However, the FILE structure, internally, may have indexes or "pointers" to the underlying O/S file. Hence, the confusion in terminology. Hope that helps.
You are right fp is never changed by fread, fseekor other f... functions. Except, of course, if you do fp = fopen(...), but then you are assigning the return value of fopen to fp and then fp changes of course.
Remember, in C parameters are passed by value, so fread cannot change it's value.
But fread does change the internal structure fp points to.
You made some confusion between a file pointer, under common definition, and the pointer in the file.
Normally with the term file pointer we refer to a pointer to a FILE structure. That structure contains all variables necessary to manage file access. This structure is created upon a successful opening of a file, and remains the same (same address) for all the time until you fclose() the file (when became undefined).
Inside the FILE structure there are many pointers that points to the file block on disk and to the position inside the current record. These pointers, managed by file I/O routines, changes when file is accessed (read or write).
And these pointers are that to which the answer you cited refers.

File pointer in c

I am trying to understand what does file pointer increment means .
I have declared file pointer fp and assuming that when I use fopen for any file (say test99.txt) and try to read it then
compiler dynamically allocate memory ( in heap ofcourse because I think internally fopen make use of malloc in order to put file in main memory)
and once file stream/data of file is put in memory then I am assuming fp contains the start address of that file stream.
Now incrementing fp by 1 (++fp) which is pointer of type FILE will increase/hop the position of fp by total size of data/stream inside that file
test99.txt. If not, and let's say incrementing fp will move fp pointer to the next character (1 byte) within the file stream then why is the below output ? ( why fp moved by 16 bytes:see the diff)
Where am I misunderstanding .
Information : size of file is 66 bytes(8KB) . Using program on unix platform on 64 bit machine (ia64 hp server) . Compiler is of HP HP-ACC-Link. Program in C
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
char ch;
fp=fopen("/home/akhils/file_dir/test99.txt","r");
printf("Address of file is %d", fp);
printf("\nLet's see value of ++fp %d\n", ++fp);
fclose(fp);
}
Output : Address of file is 2130569600
Let's see value of ++fp 2130569616
You should not be incrementing FILE* pointers, it only points to one FILE structure allocated by fopen for you.
fp is a pointer to object of type FILE. It doesn't refer to any data of the actual file, it contains some internal data like handles and stuff.
When you increase this pointer, it is increased by the size of the FILE object (it depends on implementation, 16 bytes in your example). So if it was 2130569600, it will become 2130569616. But if you try to access something by this incremented address, you will probably get an error.
The incremental function adds a number which is the weight of the type you are using.
For pointers, it permits you to go to the next pointer if you have a table of pointer. Otherwise, it's a bad use.
Here, it adds 16 bytes to the original address because a FILE pointer weight 16 bytes, like all pointers. Like Maxim Egorushkin said, it only point to the the structure allocated.
Sorry for my bad english, I hope I'll be helpfull for you.

C - print in Stream array byte with variable size

I'm designing a system where I read from a SD card and send the information via Bluetooth.
To do that, firstly I ready data from a SD card and store the bytes in an array byte of a fixed length:
char final_name[17];
And to send it via Bluetooth, I defined the Bluetooth as a stream, and I'm calling printf to send data:
fprintf(BLUETOOTH, final_name);
The problem here:
This function was designed to work with:
int fprintf(FILE *stream, const char *format, …);
so this works perfect and only 8 bytes are sent:
fprintf(BLUETOOTH, "name.txt");
But I need to send a variable size byte array. I was looking for similar functions to fprintf but where you can expecified the lenght of bytes you want to print, but I couldn't find.
Does anyone knows witha format simiar to:
int fprintf(FILE *stream, char *format, int lenght);
You can use fwrite for writing an arbitrary data with a given length into a file (or device file), not only strings.

Resources