-
-
Save anonymous/1633bf1eb90955a624de223853693e6c to your computer and use it in GitHub Desktop.
Sockets: Server accepts file from Client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define WIN32_LEAN_AND_MEAN | |
#ifdef _WIN32 | |
#include <winsock2.h> | |
#include <windows.h> | |
#include <sys/types.h> | |
#include <ws2tcpip.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <conio.h> | |
#else | |
#include <sys/socket.h> | |
#include <netdb.h> | |
#include <arpa/inet.h> | |
#include <openssl/md5.h> | |
#endif | |
#pragma comment(lib, "ws2_32.lib") // Link with Ws2_32.lib | |
#define NUM_PENDING_CONNECTIONS 5 | |
static const char NAME_S[10] = "SERVER"; | |
static const char NAME_C[10] = "CLIENT"; | |
static const char helpMessage[] = "fsnd[OPTIONS] dest_ip file\n\t-h\t\tPrints this help screen\n\t-v\t\tVerbose output\n\t-p port\t\tSet the port to connect on (e.g., 9285)\n\t-n bytes\tOffset into file to start sending\n\t-l\t\tListen (on server side) on port instead of connecting"; | |
typedef struct sockaddr_in SockAddress; | |
/* Server Commands: | |
-h // Prints this help screen | |
-v // Verbose output | |
-p port // Set the port to connect on (e.g., 9285) | |
-n bytes // Offset into file to start sending | |
-l // Listen (on server side) on port instead of connecting | |
and write output to file and dest_ip refers to which ip | |
to bind to. (default: localhost) | |
*/ | |
void errorVandL(); | |
void errorVorLorP(); | |
int main(int argc, char* argv[]) { | |
unsigned short portNumber = 0; | |
char* address; | |
char* file; | |
int offset = 0; | |
int sendSize = 0; | |
int originalFileSize = 0; | |
int fileSize = 0; | |
int argumentsClientOrServer; // 1 for client, 2 for server | |
int clientOrServer; // 1 for client, 2 for server | |
char buffer[1000]; | |
int returnValue; //retval | |
int outsideLength; //fromlen | |
int type = SOCK_STREAM; // TCP, or SOCK_DGRAM for UDP | |
struct sockaddr_in localSock, outsideSock; //local, from | |
struct hostent *host; | |
WSADATA wsaData; | |
SOCKET listenSock, msgSock; //listen_socket, msgsock | |
/* Iterate over all Arguments */ | |
int i; | |
/* Flags, IF FOUND */ | |
int lFlagFound = 0; | |
int vFlagFound = 0; | |
int pFlagFound = 0; | |
if (strcmp("fsnd", argv[1]) != 0) { | |
printf("You entered the wrong program arguments...\n"); | |
printf("The correct format is: \n\t>> fsnd -l -p 9825 127.0.0.1\n"); | |
Sleep(5000); | |
return 1; | |
} | |
if (strcmp("-p", argv[2]) == 0) { | |
argumentsClientOrServer = 1; | |
} else { | |
argumentsClientOrServer = 2; | |
} | |
for (i = 1; i < argc; i++) { | |
/* Help message "-h" */ | |
if (strcmp("-h", argv[i]) == 0) { | |
printf("%s", helpMessage); | |
return 0; | |
} | |
/* Server indicator "-l" listen mode */ | |
if (strcmp("-l", argv[i]) == 0) { | |
clientOrServer = 2; | |
lFlagFound = 1; | |
} | |
if (strcmp("-v", argv[i]) == 0) { | |
clientOrServer = 1; | |
vFlagFound = 1; | |
} | |
/* Port number "-p" */ | |
if (strcmp("-p", argv[i]) == 0) { | |
portNumber = atoi(argv[i + 1]); | |
pFlagFound = 1; | |
} | |
/* Offset "-o" */ | |
if (strcmp("-o", argv[i]) == 0) { | |
offset = atoi(argv[i + 1]); | |
} | |
/* Sendsize "-n" */ | |
if (strcmp("-n", argv[i]) == 0) { | |
sendSize = atoi(argv[i + 1]); | |
} | |
} | |
// testing only | |
//printf("%s", argv[argc - 1]); | |
address = argv[argc - 2]; | |
file = argv[argc - 1]; | |
if (lFlagFound == 1 && vFlagFound == 1) { | |
errorVandL(); | |
return 1; | |
} | |
if (lFlagFound == 0 && vFlagFound == 0 && pFlagFound == 0) { | |
errorVorLorP(); | |
return 1; | |
} | |
if (argc > 12) { | |
printf("Error: Check the number of arguments you have!\n"); | |
printf("\tYou currently have %d arguments!\n", argc); | |
return -1; | |
} | |
/* Checks to see if IP Address exists */ | |
if (address == NULL) { | |
printf("Error: No IP Address found! Check your arguments!\n"); | |
printf("%s", helpMessage); | |
return -1; | |
} | |
/* Checks to see if Port Number exists */ | |
if (portNumber <= 0) { | |
printf("Error: No port number found! Check your arguments!\n"); | |
printf("%s", helpMessage); | |
return -1; | |
} | |
/* Client */ | |
if (clientOrServer == 1) { | |
char clientBuffer[9000]; | |
unsigned int addr; | |
struct sockaddr_in server; | |
SOCKET clientSock; | |
if (returnValue = WSAStartup(0x202, &wsaData) != 0) { | |
printf("%s: WSAStartup failed! Error: %d - BAD!\n", NAME_C, returnValue); | |
WSACleanup(); | |
return -1; | |
} else { | |
printf("%s: WSAStartup success! - GOOD!\n", NAME_C); | |
} | |
addr = inet_addr(address); | |
host = gethostbyaddr((char*) &addr, 4, AF_INET); | |
if (host == NULL) { | |
printf("%s: Obtaining host by address failed! Error: %d - BAD!\n", NAME_C, WSAGetLastError()); | |
WSACleanup(); | |
return 1; | |
} else { | |
printf("%s: Obtained host by address success! - GOOD!\n", NAME_C); | |
} | |
/* Information being transferred into the sockaddr_in structures */ | |
memset(&server, 0, sizeof(server)); | |
memcpy(&(server.sin_addr), host -> h_addr, host -> h_length); | |
server.sin_family = host -> h_addrtype; | |
server.sin_port = htons(portNumber); | |
/* Opens the socket */ | |
clientSock = socket(AF_INET, type, 0); | |
if (clientSock < 0) { | |
printf("%s: Cannot open the socket! Error: %d - BAD!\n", NAME_C, WSAGetLastError()); | |
WSACleanup(); | |
return -1; | |
} else { | |
printf("%s: Opened the socket success! - GOOD!\n\n", NAME_C); | |
} | |
/* Stream in the file */ | |
FILE *fp; | |
long lOffset = offset; | |
if ((fp = fopen(file, "rb")) == NULL) { | |
printf("%s: Error: Cannot open the file: %s!\n", NAME_C, file); | |
return 1; | |
} else { | |
/* Original file size */ | |
fseek(fp, 0L, SEEK_END); | |
originalFileSize = ftell(fp); | |
rewind(fp); // seek back to the beginning so we can implement offset | |
/* Seek from offset into the file */ | |
//fseek(fp, 0L, SEEK_END); | |
fseek(fp, sendSize, SEEK_SET); // seek to sendSize | |
fileSize = ftell(fp); // get current file pointer | |
//fseek(fp, 0, SEEK_SET); // seek back to beginning of file | |
} | |
printf("%s: Connected to IP: %s\n", NAME_C, address); | |
printf("%s: On port: %d\n", NAME_C, portNumber); | |
printf("%s: File name: %s\n", NAME_C, file); | |
printf("%s: File size: %d bytes\n", NAME_C, originalFileSize); | |
printf("%s: Sending file [offset = %d | send size = %d]\n", NAME_C, offset, sendSize); | |
if (connect(clientSock, (struct sockaddr*) &server, sizeof(server)) < 0) { | |
printf("\n%s: Connection to server failed! Error: %d - BAD!\n", NAME_C, WSAGetLastError()); | |
WSACleanup(); | |
return -1; | |
} else { | |
//printf("Connection success!"); | |
} | |
/* Read data from file and send it */ | |
float total = 0; | |
float fFileSize = fileSize; | |
float percentage; | |
if (fFileSize < 1) { | |
fFileSize = originalFileSize; | |
} | |
/* Send server how big the file is */ | |
unsigned int theSize = fileSize; | |
//write(clientSock, sendSize, 1); | |
if (sendSize <= 0) { | |
for (;;) { | |
unsigned char buff[256] = {0}; | |
float nread = fread(buff, 1, 256, fp); | |
total = total + nread; | |
percentage = (total / fFileSize) * 100; | |
printf("\r%s: Percentage sent: %.2f", NAME_C, percentage); | |
/* Send data in 256 byte chunks */ | |
if (nread > 0) { | |
write(clientSock, buff, nread); | |
} | |
if (nread < 256) { | |
if (feof(fp)) { | |
printf("\nSend Success!\n"); | |
break; | |
} | |
} | |
} | |
printf("%.2f", total); | |
} else { | |
for (;;) { | |
unsigned char buff[256] = {0}; | |
float nread = fread(buff, 1, sendSize, fp); | |
total = total + nread; | |
percentage = (total / sendSize) * 100; | |
printf("\r%s: Percentage sent: %.2f", NAME_C, percentage); | |
if (nread >= sendSize) { | |
break; | |
} | |
} | |
} | |
//printf("\n%.0f bytes sent!", total); | |
} | |
/* Server */ | |
if (clientOrServer == 2) { | |
/* WSAStartup requesting Winsock */ | |
if ((returnValue = WSAStartup(0x202, &wsaData)) != 0) { | |
printf("%s: WSAStartup failed! Error: %d - BAD!\n", NAME_S, returnValue); | |
WSACleanup(); | |
return -1; | |
} else { | |
printf("%s: WSAStartup success! - GOOD!\n", NAME_S); | |
} | |
localSock.sin_family = AF_INET; | |
localSock.sin_addr.s_addr = inet_addr("127.0.0.1"); // or INADDR_ANY | |
localSock.sin_port = htons(portNumber); | |
listenSock = socket(AF_INET, type, 0); | |
/* Creating the Socket */ | |
if (listenSock == INVALID_SOCKET) { | |
printf("%s: Socket failed! Error: %d - BAD!\n", NAME_S, WSAGetLastError()); | |
WSACleanup(); | |
return -1; | |
} else { | |
printf("%s: Socket created! - GOOD!\n", NAME_S); | |
} | |
/* Binding with the Socket */ | |
if (bind(listenSock, (struct sockaddr*) &localSock, sizeof(localSock)) == SOCKET_ERROR) { | |
printf("%s: Binding with Socket failed! Error: %d - BAD!\n", NAME_S, WSAGetLastError()); | |
WSACleanup(); | |
return -1; | |
} else { | |
printf("%s: Bind success! - GOOD!\n", NAME_S); | |
} | |
/* If the Socket is not UDP -- Opposite if type == SOCK_DGRAM*/ | |
if (listen(listenSock, 5) == SOCKET_ERROR) { | |
printf("%s: Listen failed! Error: %d - BAD!\n", NAME_S, WSAGetLastError()); | |
WSACleanup(); | |
return -1; | |
} else { | |
printf("%s: Listen success! - GOOD!\n", NAME_S); | |
} | |
//printf("\nSockets connection looks good. Listening...\n"); | |
//Sleep(4000); // Delay for 4 seconds | |
//system("@cls||clear"); // Clears the screen | |
printf("\n%s: Listening on port: %d\n", NAME_S, portNumber); | |
printf("\n%s: Receiving file: \n", NAME_S); | |
printf("%s: Percentage received: \n", NAME_S); | |
// On completion | |
printf("%s: Receive success!\n", NAME_S); | |
//printf("%s: File size received: %d\n", NAME_S, sizeof(buffer)); | |
while (1) { | |
outsideLength = sizeof(outsideSock); | |
msgSock = accept(listenSock, (struct sockaddr*) & outsideSock, &outsideLength); | |
if (msgSock == INVALID_SOCKET) { | |
printf("%s: Accept failed! Error: %d - BAD!\n", NAME_S, WSAGetLastError()); | |
WSACleanup(); | |
return -1; | |
} else { // can be commented out | |
printf("%s: Accepted connection from %s", inet_ntoa(outsideSock.sin_addr)); | |
} | |
returnValue = recv(msgSock, buffer, sizeof(buffer), 0); | |
if (returnValue == SOCKET_ERROR) { | |
printf("%s: Receive failed! Error: %d - BAD!\n", NAME_S, WSAGetLastError()); | |
closesocket(msgSock); | |
continue; | |
} else { | |
printf("%s: Receive success! - GOOD!\n", NAME_S); | |
} | |
if (returnValue == 0) { | |
printf("\n%s: Client has closed their connection.\n", NAME_S); | |
closesocket(msgSock); | |
continue; | |
} | |
/* Receive data from client */ | |
FILE *fp; | |
float total = 0; | |
float bytesReceived = 0; | |
char buff[256]; | |
memset(buff, '0', sizeof(buff)); | |
float percentage = (total / bytesReceived) * 100; | |
while ((bytesReceived = read(msgSock, buff, 256)) > 0) { | |
fwrite(buff, sizeof(char), sizeof(buff), fp); | |
printf("\r%s: Percentage received: %.2f", NAME_C, percentage); | |
} | |
} | |
} | |
return 0; | |
} | |
void errorVandL() { | |
printf("Error: You can't have both -v and -l flags together!\n"); | |
} | |
void errorVorLorP() { | |
printf("Error: There were no -v, -l, nor -p flags found in arguments!\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment