Advertisement
Guest User

client.c

a guest
Nov 27th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.46 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <errno.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <netdb.h>
  9. #include <netinet/in.h>
  10. #include <arpa/inet.h>
  11. #include <sys/wait.h>
  12. #include <signal.h>
  13. #include <netdb.h>
  14. #include <pthread.h>
  15. #include <time.h>
  16. #define MAXBUF 1024
  17. #define packetSize 256
  18. #define payloadSize 248
  19. #define headerSize 8
  20.  
  21. char input[MAXBUF];
  22. int udpSocket;
  23. int returnStatus;
  24. int addrlen;
  25. int clientId;
  26. int windowSize;
  27. int totalNumPackets;
  28. int numAcksSent = 0;
  29. int numNacksSent = 0;
  30. struct sockaddr_in udpClient, udpServer;
  31. char buf[MAXBUF];
  32. char username[256];
  33. char password[256];
  34. char filename[256];
  35. char header[headerSize];
  36. char *dataBuffer = NULL;
  37. char packetBuffer[packetSize];
  38. char payloadBuffer[payloadSize];
  39. int *ackList = NULL;
  40. FILE *outFP;
  41.  
  42. int main(int argc, char* argv[]) {
  43.    
  44.     if (argc < 5) {
  45.         fprintf(stderr, "Usage: %s <ip address> <port> <input filename> <output filename>\n", argv[0]);
  46.         exit(1);
  47.     }
  48.  
  49.     /* create a socket */
  50.     udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
  51.     if (udpSocket == -1) {
  52.         fprintf(stderr, "Could not create a socket!\n");
  53.         exit(1);
  54.     } else {
  55.         printf("Socket created.\n");    
  56.     }
  57.  
  58.     /* client address */
  59.     /* use INADDR_ANY to use all local addresses */
  60.     udpClient.sin_family = AF_INET;
  61.     udpClient.sin_addr.s_addr = INADDR_ANY;
  62.     udpClient.sin_port = 0;
  63.     returnStatus = bind(udpSocket, (struct sockaddr*)&udpClient, sizeof(udpClient));
  64.  
  65.     if (returnStatus == 0) {
  66.         fprintf(stderr, "Bind completed!\n");
  67.     } else {
  68.         fprintf(stderr, "Could not bind to address!\n");
  69.         close(udpSocket);
  70.         exit(1);
  71.     }
  72.  
  73.     /* server address */
  74.     /* use the command-line arguments */
  75.     udpServer.sin_family = AF_INET;
  76.     udpServer.sin_addr.s_addr = inet_addr(argv[1]);
  77.     udpServer.sin_port = htons(atoi(argv[2]));
  78.  
  79.     printf("Welcome!\n");
  80.  
  81.     // authentication loop
  82.     while(1) {
  83.         printf("Please enter your username: ");
  84.         scanf("%s", username);
  85.  
  86.         printf("Please enter your password: ");
  87.         scanf("%s", password);
  88.  
  89.         // send username
  90.         returnStatus = sendto(udpSocket, username, strlen(username)+1, 0,
  91.             (struct sockaddr*)&udpServer, sizeof(udpServer));
  92.  
  93.         if (returnStatus == -1) {
  94.             fprintf(stderr, "Could not send username!\n");
  95.             exit(1);
  96.         }
  97.         printf("Username sent.\n");
  98.  
  99.         // send password
  100.         returnStatus = sendto(udpSocket, password, strlen(password)+1, 0,
  101.             (struct sockaddr*)&udpServer, sizeof(udpServer));
  102.  
  103.         if (returnStatus == -1) {
  104.             fprintf(stderr, "Could not send password!\n");
  105.             exit(1);
  106.         }
  107.         printf("Password sent.\n");
  108.  
  109.         /* message sent: look for confirmation */
  110.         addrlen = sizeof(udpServer);
  111.         returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0, (struct sockaddr*)&udpServer, &addrlen);
  112.         if (returnStatus == -1) {
  113.            fprintf(stderr, "Did not receive confirmation!\n");
  114.            continue;
  115.         }
  116.         printf("Received: %s\n", buf);
  117.         if(!strcmp(buf, "0")) {
  118.             printf("Authentication failed. Try again.\n");
  119.             continue;
  120.         }
  121.         printf("Authenticated.\n");
  122.         break;
  123.     }
  124.    
  125.     // file loop
  126.     int isFirst = 1;
  127.     while(1) {
  128.  
  129.         // get filename from stdin or command line
  130.         if(!isFirst) {
  131.             printf("Please enter your filename: ");
  132.             scanf("%s", filename);
  133.         } else { strcpy(filename, argv[3]); }
  134.         isFirst = 0;
  135.  
  136.         // send filename
  137.         returnStatus = sendto(udpSocket, filename, strlen(filename)+1, 0,
  138.             (struct sockaddr*)&udpServer, sizeof(udpServer));
  139.         if (returnStatus == -1) {
  140.             fprintf(stderr, "Could not send filename!\n");
  141.             continue;
  142.         }
  143.         printf("Sent request for file: %s.\n", filename);
  144.  
  145.         // receive confirmation from server
  146.         returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0, (struct sockaddr*)&udpServer, &addrlen);
  147.         if (returnStatus == -1) {
  148.            fprintf(stderr, "Did not receive file confirmation!\n");
  149.            continue;
  150.         }
  151.         printf("Received: %s\n", buf);
  152.         if(!strcmp(buf, "0")) {
  153.             printf("File retrieve failed.\n");
  154.             continue;
  155.         }
  156.         printf("File found.\n");
  157.         break;
  158.     }
  159.  
  160.     // receive window size
  161.     returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0, (struct sockaddr*)&udpServer, &addrlen);
  162.     windowSize = atoi(buf);
  163.     printf("Window size: %d\n", windowSize);
  164.  
  165.     // receive expected number of packets
  166.     returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0, (struct sockaddr*)&udpServer, &addrlen);
  167.     totalNumPackets = atoi(buf);
  168.     printf("Number of packets: %d\n", totalNumPackets);
  169.  
  170.     // allocate memory for whole file
  171.     dataBuffer = (char*) malloc(sizeof(char)*packetSize*totalNumPackets);
  172.     ackList = (int*) malloc(sizeof(int)*totalNumPackets);
  173.     for(int i = 0; i < totalNumPackets; i++) { ackList[i] = 0; }
  174.  
  175.     while(1) {
  176.         // check if all packets received
  177.         int yesCount = 0;
  178.         for(int i = 0; i < totalNumPackets; i++) {
  179.             if(ackList[i] == 1) yesCount++;
  180.         }
  181.         if(yesCount == totalNumPackets) {
  182.             printf("Whole file received!!\n");
  183.             break;
  184.         }
  185.  
  186.         // receive packet
  187.         printf("Waiting for packet...\n");
  188.         returnStatus = recvfrom(udpSocket, packetBuffer, packetSize, 0, (struct sockaddr*)&udpServer, &addrlen);
  189.  
  190.         // strip header
  191.         strncpy(header, packetBuffer, headerSize);
  192.         int receivedPacket = atoi(header);
  193.         printf("Received packet: %d\n", receivedPacket);
  194.  
  195.         // strip payload
  196.         strncpy(payloadBuffer, &packetBuffer[headerSize], payloadSize);
  197.         // printf("%s\n", payloadBuffer);
  198.  
  199.         // build response
  200.         char response[headerSize+3] = "ACK";
  201.         strcat(response, header);
  202.         printf("%s\n", response);
  203.  
  204.         // store packet and confirm receipt
  205.         ackList[receivedPacket] = 1;
  206.         strncpy(&dataBuffer[receivedPacket*payloadSize], payloadBuffer, payloadSize);
  207.         returnStatus = sendto(udpSocket, response, strlen(response)+1, 0,
  208.             (struct sockaddr*)&udpServer, sizeof(udpServer));
  209.         numAcksSent++;
  210.     }
  211.  
  212.     // write to file
  213.     outFP = fopen(argv[4], "w");
  214.     fputs(dataBuffer, outFP);
  215.     fclose(outFP);
  216.  
  217.     // calc date
  218.     time_t t = time(NULL);
  219.     struct tm *tm = localtime(&t);
  220.     char time[64];
  221.     strftime(time, sizeof(time), "%c", tm);
  222.  
  223.     printf("\n=== METRICS ===\n");
  224.     // Name and Size of the file that was received
  225.     printf("Received file '%s' (%d bytes)\n", filename, (int)strlen(dataBuffer));
  226.     // File Creation Date & Time
  227.     printf("File created: %s\n", time);
  228.     // Number of Data Packets received
  229.     printf("Packets received: %d\n", totalNumPackets);
  230.     // Number of Acknowledgement Sent
  231.     printf("Sent %d ACKs.\n", numAcksSent);
  232.     // Number of Negative Acknowledgement Sent
  233.     printf("Sent %d NACKs.\n", numNacksSent);
  234.  
  235.     /* cleanup */
  236.     close(udpSocket);
  237.     free(dataBuffer);
  238.     return 0;
  239. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement