Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <sys/wait.h>
- #include <signal.h>
- #include <netdb.h>
- #include <pthread.h>
- #include <time.h>
- #define MAXBUF 1024
- #define packetSize 256
- #define payloadSize 248
- #define headerSize 8
- char input[MAXBUF];
- int udpSocket;
- int returnStatus;
- int addrlen;
- int clientId;
- int windowSize;
- int totalNumPackets;
- int numAcksSent = 0;
- int numNacksSent = 0;
- struct sockaddr_in udpClient, udpServer;
- char buf[MAXBUF];
- char username[256];
- char password[256];
- char filename[256];
- char header[headerSize];
- char *dataBuffer = NULL;
- char packetBuffer[packetSize];
- char payloadBuffer[payloadSize];
- int *ackList = NULL;
- FILE *outFP;
- int main(int argc, char* argv[]) {
- if (argc < 5) {
- fprintf(stderr, "Usage: %s <ip address> <port> <input filename> <output filename>\n", argv[0]);
- exit(1);
- }
- /* create a socket */
- udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
- if (udpSocket == -1) {
- fprintf(stderr, "Could not create a socket!\n");
- exit(1);
- } else {
- printf("Socket created.\n");
- }
- /* client address */
- /* use INADDR_ANY to use all local addresses */
- udpClient.sin_family = AF_INET;
- udpClient.sin_addr.s_addr = INADDR_ANY;
- udpClient.sin_port = 0;
- returnStatus = bind(udpSocket, (struct sockaddr*)&udpClient, sizeof(udpClient));
- if (returnStatus == 0) {
- fprintf(stderr, "Bind completed!\n");
- } else {
- fprintf(stderr, "Could not bind to address!\n");
- close(udpSocket);
- exit(1);
- }
- /* server address */
- /* use the command-line arguments */
- udpServer.sin_family = AF_INET;
- udpServer.sin_addr.s_addr = inet_addr(argv[1]);
- udpServer.sin_port = htons(atoi(argv[2]));
- printf("Welcome!\n");
- // authentication loop
- while(1) {
- printf("Please enter your username: ");
- scanf("%s", username);
- printf("Please enter your password: ");
- scanf("%s", password);
- // send username
- returnStatus = sendto(udpSocket, username, strlen(username)+1, 0,
- (struct sockaddr*)&udpServer, sizeof(udpServer));
- if (returnStatus == -1) {
- fprintf(stderr, "Could not send username!\n");
- exit(1);
- }
- printf("Username sent.\n");
- // send password
- returnStatus = sendto(udpSocket, password, strlen(password)+1, 0,
- (struct sockaddr*)&udpServer, sizeof(udpServer));
- if (returnStatus == -1) {
- fprintf(stderr, "Could not send password!\n");
- exit(1);
- }
- printf("Password sent.\n");
- /* message sent: look for confirmation */
- addrlen = sizeof(udpServer);
- returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0, (struct sockaddr*)&udpServer, &addrlen);
- if (returnStatus == -1) {
- fprintf(stderr, "Did not receive confirmation!\n");
- continue;
- }
- printf("Received: %s\n", buf);
- if(!strcmp(buf, "0")) {
- printf("Authentication failed. Try again.\n");
- continue;
- }
- printf("Authenticated.\n");
- break;
- }
- // file loop
- int isFirst = 1;
- while(1) {
- // get filename from stdin or command line
- if(!isFirst) {
- printf("Please enter your filename: ");
- scanf("%s", filename);
- } else { strcpy(filename, argv[3]); }
- isFirst = 0;
- // send filename
- returnStatus = sendto(udpSocket, filename, strlen(filename)+1, 0,
- (struct sockaddr*)&udpServer, sizeof(udpServer));
- if (returnStatus == -1) {
- fprintf(stderr, "Could not send filename!\n");
- continue;
- }
- printf("Sent request for file: %s.\n", filename);
- // receive confirmation from server
- returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0, (struct sockaddr*)&udpServer, &addrlen);
- if (returnStatus == -1) {
- fprintf(stderr, "Did not receive file confirmation!\n");
- continue;
- }
- printf("Received: %s\n", buf);
- if(!strcmp(buf, "0")) {
- printf("File retrieve failed.\n");
- continue;
- }
- printf("File found.\n");
- break;
- }
- // receive window size
- returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0, (struct sockaddr*)&udpServer, &addrlen);
- windowSize = atoi(buf);
- printf("Window size: %d\n", windowSize);
- // receive expected number of packets
- returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0, (struct sockaddr*)&udpServer, &addrlen);
- totalNumPackets = atoi(buf);
- printf("Number of packets: %d\n", totalNumPackets);
- // allocate memory for whole file
- dataBuffer = (char*) malloc(sizeof(char)*packetSize*totalNumPackets);
- ackList = (int*) malloc(sizeof(int)*totalNumPackets);
- for(int i = 0; i < totalNumPackets; i++) { ackList[i] = 0; }
- while(1) {
- // check if all packets received
- int yesCount = 0;
- for(int i = 0; i < totalNumPackets; i++) {
- if(ackList[i] == 1) yesCount++;
- }
- if(yesCount == totalNumPackets) {
- printf("Whole file received!!\n");
- break;
- }
- // receive packet
- printf("Waiting for packet...\n");
- returnStatus = recvfrom(udpSocket, packetBuffer, packetSize, 0, (struct sockaddr*)&udpServer, &addrlen);
- // strip header
- strncpy(header, packetBuffer, headerSize);
- int receivedPacket = atoi(header);
- printf("Received packet: %d\n", receivedPacket);
- // strip payload
- strncpy(payloadBuffer, &packetBuffer[headerSize], payloadSize);
- // printf("%s\n", payloadBuffer);
- // build response
- char response[headerSize+3] = "ACK";
- strcat(response, header);
- printf("%s\n", response);
- // store packet and confirm receipt
- ackList[receivedPacket] = 1;
- strncpy(&dataBuffer[receivedPacket*payloadSize], payloadBuffer, payloadSize);
- returnStatus = sendto(udpSocket, response, strlen(response)+1, 0,
- (struct sockaddr*)&udpServer, sizeof(udpServer));
- numAcksSent++;
- }
- // write to file
- outFP = fopen(argv[4], "w");
- fputs(dataBuffer, outFP);
- fclose(outFP);
- // calc date
- time_t t = time(NULL);
- struct tm *tm = localtime(&t);
- char time[64];
- strftime(time, sizeof(time), "%c", tm);
- printf("\n=== METRICS ===\n");
- // Name and Size of the file that was received
- printf("Received file '%s' (%d bytes)\n", filename, (int)strlen(dataBuffer));
- // File Creation Date & Time
- printf("File created: %s\n", time);
- // Number of Data Packets received
- printf("Packets received: %d\n", totalNumPackets);
- // Number of Acknowledgement Sent
- printf("Sent %d ACKs.\n", numAcksSent);
- // Number of Negative Acknowledgement Sent
- printf("Sent %d NACKs.\n", numNacksSent);
- /* cleanup */
- close(udpSocket);
- free(dataBuffer);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement