cnos-assignment-2/server1.c
2021-02-28 12:00:26 +10:30

174 lines
4.0 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <strings.h>
#include <getopt.h>
#define BUFFER_LENGTH 512
#define BACKLOG 1
void usage(char* programName);
int create_server_socket(int port);
struct sockaddr_in socket_server, socket_client;
int main(int argc, char** argv)
{
int sfd, fd;
long int n, m, count = 0;
unsigned int nsid;
ushort client_port;
char buffer[BUFFER_LENGTH], filename[256];
char dst[INET_ADDRSTRLEN];
time_t intps;
struct tm* tmi;
// Parse options
char argchar;
while ((argchar = getopt(argc, argv, "")) != -1)
{
switch (argchar)
{
default:
break;
}
}
// Parse positional arguments
int port;
char* file_path;
if (argv[optind] == NULL || argv[optind + 1] == NULL)
{
usage(argv[0]);
exit(3);
}
else
{
port = atoi(argv[optind]);
file_path = argv[optind + 1];
}
// Open a TCP socket over IPv4
sfd = socket(AF_INET, SOCK_SEQPACKET, 0);
if (sfd == -1)
{
perror("socket fail");
exit(EXIT_SUCCESS);
}
// Set socket options
int yes = 1;
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
{
perror("setsockopt error");
exit(5);
}
// Clear out the server socket address struct
int sockaddr_size = sizeof(struct sockaddr_in);
bzero(&socket_server, sockaddr_size);
// Define properties of server socket address
socket_server.sin_family = AF_INET;
socket_server.sin_port = htons(port);
socket_server.sin_addr.s_addr = htonl(0); // <-- 0.0.0.0, binds to all interfaces
// Bind the socket to the address
if (bind(sfd, (struct sockaddr*) &socket_server, sockaddr_size) == -1)
{
perror("bind fail");
exit(EXIT_FAILURE);
}
// Clear message buffer
bzero(buffer, BUFFER_LENGTH);
// Start listening for connections, allowing a maximum of BACKLOG waiting connections
listen(sfd, BACKLOG);
// Block and accept incoming connection
// TODO: Figure out what socklen actually is and why it's here
socklen_t socklen;
nsid = accept(sfd, (struct sockaddr*) &socket_client, &socklen);
//
if (nsid == -1)
{
perror("accept fail");
exit(EXIT_FAILURE);
}
if(inet_ntop(AF_INET, &socket_client.sin_addr, dst, INET_ADDRSTRLEN) == NULL)
{
perror("socket error");
exit (4);
}
client_port = ntohs(socket_client.sin_port);
printf("connection : %s:%d\n", dst, client_port);
bzero(filename, 256);
intps = time(NULL);
tmi = localtime(&intps);
bzero(filename, 256);
sprintf(filename, "saved-file.%d.%d.%d.%d.%d.%d", tmi->tm_mday, tmi->tm_mon+1, 1900+tmi->tm_year, tmi->tm_hour, tmi->tm_min, tmi->tm_sec);
printf("Creating the copied output file : %s\n", filename);
if ((fd = open(filename, O_CREAT | O_WRONLY, 0600)) == -1)
{
perror("open fail");
exit(3);
}
bzero(buffer, BUFFER_LENGTH);
n = recv(nsid, buffer, BUFFER_LENGTH, 0);
while(n)
{
if (n==-1)
{
perror("recv fail");
exit(5);
}
if ((m=write(fd,buffer,n))==-1)
{
perror("write fail");
exit(6);
}
count += m;
bzero(buffer, BUFFER_LENGTH);
n = recv(nsid, buffer, BUFFER_LENGTH, 0);
}
close(sfd);
close(fd);
close(nsid);
printf("End of transmission with %s.%d\n", dst, client_port);
/* Select the appropriate variable in the following function call argument */
printf("Number of octets received : %ld \n", /* Q) What goes here? */);
return EXIT_SUCCESS;
}
void usage(char* programName)
{
fprintf(stderr, "Usage: %s [OPTIONS] <port-number> <file-to-send>\n", programName);
}