This is a more sophisticated version that can be compiled on linux (tested on UBUNTU) and on windows (test OS Win7).
It transfers more files. It is not optimized. It has not all checks required.
Include file preamble.h
typedef struct
{
long long llSize;
char FileName[500];
char Reserved[8];
} FILEDATA;
The server:
#ifdef __linux__
#define _FILE_OFFSET_BITS 64
#else
#include <winsock2.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#ifdef __linux__
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define WINBIN
#else
#define WINBIN "b"
#define close closesocket
#define ftell _ftell64
#define ioctl ioctlsocket
typedef int socklen_t;
#endif
#include "preamble.h"
char *file[] = { "mp3.mp3" ,
"image.jpg",
"film.mkv"
};
#ifdef __linux__
char Path[] = "/media/sf_UnixShares/";
#else
char Path[] = "C:\\Users\\UnixShares\\";
#endif
int SendFile(int socket, char *FileName)
{
FILEDATA fd;
FILE *fp;
long int read_size, stat, packet_index;
long long int size=0;
char send_buffer[512];
char read_buffer[512];
char LocFname[1024];
packet_index = 1;
memset(&fd, 0, sizeof(fd));
strcpy(LocFname, Path);
strcat(LocFname, FileName);
fp = fopen(LocFname, "r" WINBIN);
if (fp == NULL)
{
printf("Error Opening File \"%s\"\n", FileName);
exit(-1);
}
printf("Getting file Size\n");
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
fd.llSize = size;
printf("Total file size: %lli \n", size);
strcpy(fd.FileName, FileName);
printf("Sending file preamble\n");
send(socket, (void *)&fd, sizeof(fd), 0);
do
{
stat = recv(socket, read_buffer, 255, 0);
printf("Bytes read: %li \n", stat);
} while (stat < 0);
printf("Received preamble acknowledge <%5s>\n", read_buffer);
if (strncmp("OK", read_buffer, 5))
{
printf ("Transfer aborted!\n");
return 0;
}
printf("Press Enter to send file: ...");
getchar();
printf("\rSending file\n");
while (!feof(fp))
{
read_size = fread(send_buffer, 1, sizeof(send_buffer), fp);
do
{
stat = send(socket, send_buffer, read_size, 0);
} while (stat < 0);
printf("\rPacket %li, sent %li bytes.", packet_index, read_size);
packet_index++;
memset(send_buffer, 0, sizeof(send_buffer));
}
printf("\nFile sent!\n");
return 1;
}
int main(int argc, char *argv[])
{
long long int socket_desc, new_socket, c;
struct sockaddr_in server, client;
#if defined(__WIN32__) || defined(_WIN32)
int iResult;
WSADATA wsaData;
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR)
{
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
#endif
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(6888);
if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0)
{
puts("bind failed");
return 1;
}
puts("Bind completed");
listen(socket_desc, 3);
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *) & c);
fflush(stdout);
if (new_socket < 0)
{
perror("Accept Failed");
return 1;
}
else
puts("Connection accepted");
for (int i=0; i<3; i++)
if (!SendFile(new_socket, file[i]))
{
printf ("Client required tx abort!\n");
break;
}
FILEDATA fd = {0};
send(new_socket, (void *)&fd, sizeof(fd), 0);
close(new_socket);
close(socket_desc);
fflush(stdout);
return 0;
}
The Client:
#ifdef __linux__
#define _FILE_OFFSET_BITS 64
#else
#include <winsock2.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#ifdef __linux__
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define WINBIN
#else
#define WINBIN "b"
#define close closesocket
#define ftell _ftell64
#define ioctl ioctlsocket
typedef int socklen_t;
#endif
#include "preamble.h"
int ReceiveFile(int socket)
{
long int buffersize = 0;
long int read_size;
long long int recv_size = 0;
FILE *fp;
FILEDATA fd;
recv(socket, (void *)&fd, sizeof(fd), 0);
if (fd.llSize <= 0)
{
printf("End of transfer or error (len=0)\n");
return 0;
}
fp = fopen(fd.FileName, "w" WINBIN);
if (fp == NULL)
{
printf("Error! Cannot create file \"%s\".\n", fd.FileName);
send(socket, "ABORT", 6, 0);
return 0;
}
printf ("Receiving %lld bytes for file \"%s\".\n", fd.llSize, fd.FileName);
send(socket, "OK", 3, 0);
while (recv_size < fd.llSize)
{
ioctl(socket, FIONREAD, (unsigned long int *)&buffersize);
if (buffersize <= 0)
continue;
if (buffersize > (fd.llSize - recv_size))
buffersize = fd.llSize - recv_size;
char *pBuf = malloc(buffersize);
if (!pBuf)
{
fprintf(stderr, "\nMemory Error. Cannot allocate!\n");
exit(-1);
}
read_size = recv(socket, pBuf, buffersize, 0);
if (read_size < 0)
{
printf("\n%s", strerror(errno));
return 0;
}
fwrite(pBuf, 1, buffersize, fp);
free(pBuf);
recv_size += read_size;
printf("\rReceived %lli bytes out of %lli.", recv_size, fd.llSize);
}
fclose(fp);
printf("\nFile successfully Received! \n");
return 1;
}
int main(int argc, char *argv[])
{
long long int socket_desc;
struct sockaddr_in server;
#if defined(__WIN32__) || defined(_WIN32)
int iResult;
WSADATA wsaData;
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR)
{
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
#endif
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1)
{
printf("Could not create socket \n");
}
memset(&server, 0, sizeof(server));
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(6888);
if (connect(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0)
{
close(socket_desc);
printf("Connect Error \n");
return -1;
}
puts("Connected \n");
while (ReceiveFile(socket_desc))
;
close(socket_desc);
return 0;
}