Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send large files over socket in C

Tags:

c

linux

sockets

ftp

I am writing a simple FTP server for a school project. Project is almost done, the only problem I do have is sending a file over socket to a client. I can't write to a socket more than 200kb of data, small files are downloaded succesfully. Can anyone tell me what is the correct way of sending large files over Linux sockets ?

Thanks in advance.

PS I am using C and 32-bit linux, server working in PORT mode, been using low level open,write,read and other functions such as sendfile,send,sendto.

like image 383
user1122920 Avatar asked Dec 30 '11 12:12

user1122920


2 Answers

you can mmap the file and write it on the socket from there, you can also get its size using fstat, like this:

fd = open(filename, O_RDONLY);
struct stat s;
fstat(fd, &s); // i get the size
adr = mmap(NULL, s.st_size, PROT_READ, MAP_SHARED, fd, 0); // i get the adress
write(socket, adr, s.st_size); // i send the file from this adress directly

You may want to send just the size of the file before you send it entirely. Your client maybe want to send you that he got the good size and that he can manage to download it.

like image 185
isabel Avatar answered Sep 23 '22 16:09

isabel


One idea might be reading the file chunk by chunk, something like:

Pseudo-code

#define CHUNK_SIZE 1000

void send(){
  uint8_t buff[CHUNK_SIZE];
  int actually_read;
  while((actually_read = read(fd, buff, sizeof(buff)) > 0)
     sendto(sock_fd, buff, actually_read, 0);
}

You should add some error checking, but the idea is to read a considerable amount of bytes from the file you want to send and send that amount. In the server side you need to do a similar thing, by reading from the socket the arriving chunks and writing them to a file. You might want to prefix some metadata to buff just to tell the server which file you're transmitting if you want to handle multiple file transfers. Since FTP uses TCP you shouldn't worry about losing data.

Again, this is just an idea. There are multiple ways of doing this I suppose.

like image 36
Fred Avatar answered Sep 22 '22 16:09

Fred