#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#define SERVER_PORT 7780
#define SERVER_FILE_PATH "svrepository/file2.bin"
void handleClientConnection(struct sockaddr_in client);
int gServerUpload;
int gServerSocket;
int gServerFileSize;
int main(int argc, char** argv)
{
if (argc < 2)
{
fprintf(stderr, "-USAGE- %s <upload>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (atoi(argv[1]) > 65507)
{
printf("The upload rate is too high, please reconsider its size!\n");
exit(EXIT_FAILURE);
}
struct sockaddr_in server, client;
socklen_t clen = sizeof(client);
int cl_bytes;
gServerUpload = atoi(argv[1]);
if ((gServerSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket()");
exit(EXIT_FAILURE);
}
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(SERVER_PORT);
if (bind(gServerSocket, (struct sockaddr*) &server, sizeof(server)) < 0)
{
perror("bind()");
close(gServerSocket);
exit(EXIT_FAILURE);
}
printf("Server started using port %d...\n", SERVER_PORT); FILE* pFile = fopen(SERVER_FILE_PATH, "rb");
struct stat st;
stat(SERVER_FILE_PATH, &st);
gServerFileSize = st.st_size;
fclose(pFile);
printf("SERVER FILE INFO: PATH - \"%s\" | SIZE - %d bytes\n", SERVER_FILE_PATH, gServerFileSize);
for(;;)
{ if (recvfrom(gServerSocket, &cl_bytes, sizeof(int), 0, (struct sockaddr*) &client, &clen) > 0)
{
printf("Client (%s:%d) has connected!\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
printf("The client downloads %d packets (each %d bytes)\n", gServerFileSize / cl_bytes, cl_bytes);
printf("The client will%sreceive all the information at %d bytes per packet!\n\n", gServerFileSize % cl_bytes == 0 ? (" ") : (" not "), cl_bytes); int pid = fork();
if (pid == 0)
{
handleClientConnection(client);
}
else if (pid < 0)
{
perror("fork()");
close(gServerSocket);
exit(EXIT_FAILURE);
}
}
else
{
printf("A user disconnected!\n");
}
}
}
void handleClientConnection(struct sockaddr_in client)
{ sendto(gServerSocket, &gServerFileSize, sizeof(int), 0, (struct sockaddr*) &client, sizeof(client)); char* buffer = malloc(gServerUpload * sizeof(char));
FILE* pFile = fopen(SERVER_FILE_PATH, "rb"); while (fread(buffer, gServerUpload, 1, pFile) == 1)
{ if (sendto(gServerSocket, buffer, gServerUpload, 0, (struct sockaddr*) &client, sizeof(client)) > 0)
{ usleep(25000);
}
else
{
perror("sendto()");
close(gServerSocket);
exit(EXIT_FAILURE);
}
} if (buffer != NULL)
{
free(buffer);
buffer = NULL;
}
fclose(pFile);
close(gServerSocket);
exit(EXIT_SUCCESS);
}