LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 11-15-2004, 04:17 AM   #1
raszagal
LQ Newbie
 
Registered: Nov 2004
Posts: 4

Rep: Reputation: 0
Sending files over udp sockets in C


Hi
im trying to send files over a socket datagram in C between 2 clients.
Can anyone tell me whats the best way to "read" the file i want to send, and split it if necessary, and then send send it?
thks
 
Old 11-15-2004, 05:27 AM   #2
rjlee
Senior Member
 
Registered: Jul 2004
Distribution: Ubuntu 7.04
Posts: 1,990

Rep: Reputation: 67
You can use the read() method to read a file in chunks of (up to a) fixed size. Call it repeatedly, and send each packet, until you hit the end of the file. See the read manpage.

Assuming that you want to do this reliably, you'll also need some sort of CRC checksum in each packet to identify if it is corrupted in transit or not ,and a sequence number (because packets can become shuffled over longer routes). Alternativly, use TCP which handles this detail itself.

On the other side, you will need to read the file in in blocks, sort them into sequence (note that they are likely to be more-or-less in sequence), check the checksums, acknowledge the valid packets (use CRC checksums again), and then out the headers.

You should also resend packets after a timeout (see seek() and tell()) if its acknowledgement doesn't arrive, or is corrupted.

To generate a CRC checksum, I don't know of a method off-hand, but you might try searching for something suitable on sourceforge.net
 
Old 11-15-2004, 01:11 PM   #3
raszagal
LQ Newbie
 
Registered: Nov 2004
Posts: 4

Original Poster
Rep: Reputation: 0
thks
i have one more question... when i use the read() function, from what ive seen, i read it to a buffer of type char ? does it work files other
that text only files? like jpeg's etc... or do i have to read to somekind of byte stream...?
thks again :P
 
Old 11-15-2004, 01:41 PM   #4
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 58
You can read() any type of data. It's just that an unsigned char array serves as a very nice buffer for any data type.

For instance, you could have do something like this:
Code:
int num;

read(fd, &num, sizeof(int));
 
Old 11-16-2004, 03:10 AM   #5
shy
Member
 
Registered: Dec 2002
Location: Russia
Distribution: ASP linux
Posts: 94

Rep: Reputation: 15
Sending files through UDP seems to be a very strange idea. I'm almost sure you want to send the files reliably, so to do this (as rjlee pointed you) you should use some sort of CRC, sort parts of files, request resending of lost datagrams (btw, UDP datagrams can be lost even if UDP is used to communicate between 2 programs running on the same host), and so on, e.g. you have to implement TCP.

Why bother implementing it, if it's already done?
 
Old 11-16-2004, 05:37 AM   #6
raszagal
LQ Newbie
 
Registered: Nov 2004
Posts: 4

Original Poster
Rep: Reputation: 0
i have to do it by udp... its a school project and its demanded its over a udp "connection"
thks for the help
 
Old 11-16-2004, 05:41 AM   #7
shy
Member
 
Registered: Dec 2002
Location: Russia
Distribution: ASP linux
Posts: 94

Rep: Reputation: 15
Try to find IMHO the best book on socket API "UNIX network programming" by Richard Stevens. Reading it will defenitely help you in writing your program.

Last edited by shy; 11-16-2004 at 05:42 AM.
 
Old 11-16-2004, 11:28 AM   #8
rjlee
Senior Member
 
Registered: Jul 2004
Distribution: Ubuntu 7.04
Posts: 1,990

Rep: Reputation: 67
Quote:
Originally posted by raszagal
thks
i have one more question... when i use the read() function, from what ive seen, i read it to a buffer of type char ? does it work files other
that text only files? like jpeg's etc... or do i have to read to somekind of byte stream...?
thks again :P
To read non-text files, you generally specify unsigned char, but char will work just as well so long as you don't do any bitwise operations on it (<< >> & | or ^). read() itself doesn't care what type of buffer you pass it; it can even be a struct or a union so long as it's big enough to hold all the data.
 
Old 11-21-2004, 01:49 PM   #9
raszagal
LQ Newbie
 
Registered: Nov 2004
Posts: 4

Original Poster
Rep: Reputation: 0
hi again...
im having some trouble when reading the file i want to send. Im trying do build a message containing
in the first position the char 'F' ( for file) followed by file id ( an int ) a pkt_id ( an int ) and finally a block of data frm the file
im trying to send
i have this code just to try out adding info to the message im sending but it isnt writing anything to a new file.
if you could take a look... that would be great thks

-----------------------------------------------------------------------------------------------
#define FAIL 0
#define SUCCESS 1
#define BLOCKSIZE 512

int fileid = 5;
int pkt = 9;

unsigned char* write_block(unsigned char* data){
unsigned char *mensagem = (char *)calloc(1, 10 + BLOCKSIZE);
FILE *fp;
int pkt_number = 1;
int idfile = 1;
char *N="\n";
char *F="F";
mensagem[0] = 'F';
*( (int *) (mensagem + 1)) = fileid;
*( (int *) (mensagem + 5)) = pkt;
pkt++;
*( (unsigned char *) (mensagem + 9)) = data;
printf(" mensagem enviada : %s\n", mensagem);

idfile = *((int *) (mensagem + 1));
pkt_number = *((int *) (mensagem + 5));

printf("id do file : %d\n", idfile);
printf("id do pacote : %d\n", pkt_number);

return mensagem;
}

int file_size(char *infile){
FILE* fp;
unsigned char bloco[BLOCKSIZE];
unsigned char temp;
int num_read;
int size = 0;

if ((fp = fopen( infile, "rb")) == NULL){
printf("Error opening file %s for input.\n", infile);
return FAIL;
}
if ((fp = fopen("teste.o", "wb")) == NULL){
printf("Error opening file for input.\n");
return FAIL;
}
while ((num_read = fread(bloco, sizeof(char), BLOCKSIZE, fp)) > 0){
size += num_read;
temp = write_block(bloco);
fwrite( temp + 9, sizeof(char), num_read, fp);
}
printf("bytes : %d\n", size);
fclose(fp);
if (ferror(fp)){
printf("Error reading file %s\n", infile);
return FAIL;
}
return SUCCESS;
}

int main(){
file_size("fila.o");
return 0;
}

-------------------------------------------------------------------------------------------
 
Old 11-27-2004, 12:49 PM   #10
rjlee
Senior Member
 
Registered: Jul 2004
Distribution: Ubuntu 7.04
Posts: 1,990

Rep: Reputation: 67
Quote:
Originally posted by raszagal
Code:
	if ((fp = fopen( infile, "rb")) == NULL){
		printf("Error opening file %s for input.\n", infile);
		return FAIL;
	}
	if ((fp = fopen("teste.o", "wb")) == NULL){
		printf("Error opening file for input.\n");
		return FAIL;
	}
Assuming that both files open correctly, The fp pointer will now point to a structure representing the output file, teste.o. when you subsequently try to read from fp, you will be reading from the teste.o file, which will fail because the file is write-only.

You would have trapped this error if you had used errno.
Code:
#include <errno.h>
at the start of the file, then do
Code:
errno=0;
immediately before any standard I/O functions, like read or write. Then you test if errno==0 after the I/O; if not, an error has occurred and the value of errno (or the string message strerror() from string.h) will tell you what the error was.

You shouldn't assume that any I/O will be successful, because that isn't under the program's control; this applies to networked I/O as well as file or device I/O.

The result ferror() can also be used in place of errno (and is cleaner but potentially slower than errno), but you must still use it after each and every I/O call; if you do an I/O that fails followed by one that suceeds, without resetting the error state in between, then the error condition it returns could be anything.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
send/recv binary files with C++ sockets dafatdude Programming 3 02-12-2006 09:02 AM
open/query remote udp sockets in shell macie Programming 2 03-20-2005 04:45 PM
My postfix box is sending UDP FLOODS! graystarr Linux - Security 1 02-22-2005 08:19 PM
How to receive UDP and ICMP packets, by one UDP socket(PMTUD) myself_rajat Linux - Networking 0 05-28-2004 06:43 AM
sockets, UDP, using select() Pres Programming 3 08-22-2003 10:41 AM


All times are GMT -5. The time now is 02:57 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration