Codice PHP:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#define PORT 5500
#define BUFFSIZE 4096
#define MIN(_x_,_y_)(((_x_)<(_y_) )? (_x_):(_y_))
#define DEBUG 0
#define EXEC_FAILED 1
typedef struct{
char* filename;
unsigned long encoded_file_size;
}first_message;
double elapsed_time(time_t end, time_t start);
char* rate (unsigned long length, double internal);
char* find_fileName(char* path);
ssize_t send_reliable(int sd, void* buf,size_t len,char* err,const struct sockaddr* to);
unsigned long get_file_size(FILE* fin);
int main (int argc, char** argv){
FILE* fin;
first_message fs;
int sd;
struct sockaddr_in dest;
char buf[BUFFSIZE]; /*buffer for socket*/
unsigned long length, file_size,chunk_size;
time_t end,start;
double internal;
if (argc != 3) {
fprintf(stderr,"Usage: IPdestination path \n");
exit(EXEC_FAILED);
}
memset((char *)&dest, 0, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(PORT);
dest.sin_addr.s_addr = inet_addr(argv[1]); /*destination's address*/
if ((sd = socket(AF_INET,SOCK_DGRAM,0))<0) {
perror("socket creation failed");
exit(EXEC_FAILED);
}
fin = fopen(argv[2],"rb");
if (fin != NULL){
fs.filename = find_fileName(argv[2]);
fs.encoded_file_size = htonl(get_file_size(fin));
while (send_releable(sd,fs,sizeof(fs),"unable to send first message",(struct sockaddr*)&dest)<0){
send_releable(sd,fs,sizeof(fs),"unable to send first message",(struct sockaddr*)&dest);}
#ifdef DEBUG
printf("file_size %ld \n",get_file_size(fin));
printf("filename %s\n", fs.filename);
#endif
for (length=0; length < file_size; length += chunk_size ){
chunk_size = MIN(BUFFSIZE, file_size-length);
fread(buf, chunk_size,1, fin);
#ifdef DEBUG
printf("chunk_size %ld \n", chunk_size);
printf("length %ld \n", length);
#endif
start = time(NULL);
if (chunk_size != sendto(sd, buf, chunk_size,0,(struct sockaddr*)&dest, sizeof(dest))){
perror("Unable to send data");
}else {
end= time(NULL);
internal+=elapsed_time(end,start);
}
}
fclose(fin);
}else{
printf("Unable to open file");
}
if (length == file_size){
printf(" file has been sent successfully with rate %ld \n", rate (length,internal));
}
close(sd);
return 0;
}
ssize_t send_reliable(int sd, void* buf,size_t len,char* err, const struct sockaddr* to){
unsigned long byte_sent;
if(byte_sent = sendto(sd, buf, len, 0, to, sizeof(to))<0){
perror(err); }
sleep(2);
if(fcntl(sd,F_SETFL,O_NONBLOCK)==-1){
perror("Impossible to set NONBLOCK mode for the socket");
}
return recvfrom(sd, buf,len,0,NULL,NULL);
}
unsigned long get_file_size(FILE* fin){
unsigned long file_size;
fseek(fin,0, SEEK_END);
file_size = ftell(fin);
fseek(fin,0, SEEK_SET);
return file_size;
}
char* rate(unsigned long length, double internal){
static char res[15];
double udprate = (double)length/internal;
#ifdef DEBUG
printf("internal %f \n", internal);
printf("udprate %ld \n",length);
#endif
if(udprate<1024.0)
sprintf(res, "%.2f B/s",udprate);
else if(udprate < 1024.0*1024.0)
sprintf(res, "%.2f KB/s", udprate / 1024.0);
else
sprintf(res, "%.2f MB/s", udprate / (1024.0*1024.0));
return res;
}
double elapsed_time(time_t end, time_t start){
return difftime(end, start);
}
char* find_fileName(char* path){
char* token;
token = strtok(path, "/");
while(token != NULL) {
if (strpbrk(token,".") != NULL){
break; }
token = strtok(NULL, "/");
}
return token;
}