Advertisement
peterzig

C++ Server Winsock NonBlock

Apr 30th, 2020
451
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.67 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <ws2tcpip.h>
  4. #include <WinSock2.h>
  5.  
  6. #pragma comment(lib, "ws2_32.lib")
  7.  
  8. int main() {
  9.     WSADATA wsData;
  10.     WORD ver = MAKEWORD(2, 2);
  11.  
  12.     if (WSAStartup(ver, &wsData) != 0) {
  13.         std::cerr << "Error starting winsock!" << std::endl;
  14.         return -1;
  15.     }
  16.  
  17.     SOCKET listenerSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  18.     fcntl( sockfd, F_SETFL, O_NONBLOCK ); // jesli wywala tu blad to zakomentuj
  19.  
  20.     if (listenerSock == INVALID_SOCKET) {
  21.         std::cerr << "Error creating listener socket! " << WSAGetLastError() << std::endl;
  22.         WSACleanup();
  23.         return -1;
  24.     }
  25.  
  26.     sockaddr_in listenerHint;
  27.     listenerHint.sin_family = AF_INET;
  28.     listenerHint.sin_port = htons(55000);
  29.     listenerHint.sin_addr.S_un.S_addr = INADDR_ANY;
  30.  
  31.     bind(listenerSock, (sockaddr*)&listenerHint, sizeof(listenerHint));
  32.     listen(listenerSock, SOMAXCONN);
  33.  
  34.     sockaddr_in clientHint;
  35.     int clientSize = sizeof(clientHint);
  36.  
  37.     SOCKET clientSock = accept(listenerSock, (sockaddr*)&clientHint, &clientSize);
  38.  
  39.     if (clientSock == SOCKET_ERROR) {
  40.         std::cerr << "Error accept socket! " << WSAGetLastError() << std::endl;
  41.         closesocket(listenerSock);
  42.         WSACleanup();
  43.         return -1;
  44.     }
  45.  
  46.     char host[NI_MAXHOST];
  47.     char serv[NI_MAXSERV];
  48.  
  49.     if (getnameinfo((sockaddr*)&clientHint, sizeof(clientHint), host, NI_MAXHOST, serv, NI_MAXSERV, 0) == 0) {
  50.         std::cout << "Host: " << host << " connected on port: " << serv << std::endl;
  51.     }
  52.     else {
  53.         inet_ntop(AF_INET, &clientHint.sin_addr, host, NI_MAXHOST);
  54.         std::cout << "Host: " << host << " connected on port: " << ntohs(clientHint.sin_port) << std::endl;
  55.     }
  56.  
  57.     closesocket(listenerSock);
  58.  
  59.     const char* welcomeMsg = "Welcome to file server.";
  60.     bool clientClose = false;
  61.     char fileRequested[FILENAME_MAX];
  62.     const int fileAvailable = 200;
  63.     const int fileNotfound = 404;
  64.     const int BUFFER_SIZE = 1024;
  65.     char bufferFile[BUFFER_SIZE];
  66.     std::ifstream file;
  67.  
  68.     // sending welcome message
  69.     int bysendMsg = send(clientSock, welcomeMsg, strlen(welcomeMsg), 0);
  70.  
  71.     if (bysendMsg == 0) {
  72.         // error sending data - break loop
  73.         closesocket(clientSock);
  74.         WSACleanup();
  75.         return -1;
  76.     }
  77.  
  78.     do {
  79.         memset(fileRequested, 0, FILENAME_MAX);
  80.         int byRecv = recv(clientSock, fileRequested, FILENAME_MAX, 0);
  81.  
  82.         if (byRecv == 0 || byRecv == -1) {
  83.             // error receive data - break loop
  84.             clientClose = true;
  85.         }
  86.  
  87.         // open file
  88.         file.open(fileRequested, std::ios::binary);
  89.  
  90.         if (file.is_open()) {
  91.             // file is available
  92.             int bySendinfo = send(clientSock, (char*)&fileAvailable, sizeof(int), 0);
  93.             if (bySendinfo == 0 || bySendinfo == -1) {
  94.                 // error sending data - break loop
  95.                 clientClose = true;
  96.             }
  97.  
  98.             // get file size
  99.             file.seekg(0, std::ios::end);
  100.             long fileSize = file.tellg();
  101.  
  102.             // send filesize to client
  103.             bySendinfo = send(clientSock, (char*)&fileSize, sizeof(long), 0);
  104.             if (bySendinfo == 0 || bySendinfo == -1) {
  105.                 // error sending data - break loop
  106.                 clientClose = true;
  107.             }
  108.             file.seekg(0, std::ios::beg);
  109.             // read file with do-while loop
  110.             do {
  111.                 // read and send part file to client
  112.                 file.read(bufferFile, BUFFER_SIZE);
  113.                 if (file.gcount() > 0)
  114.                     bySendinfo = send(clientSock, bufferFile, file.gcount(), 0);
  115.  
  116.                 if (bySendinfo == 0 || bySendinfo == -1) {
  117.                     // error sending data - break loop
  118.                     clientClose = true;
  119.                     break;
  120.                 }
  121.             } while (file.gcount() > 0);
  122.             file.close();
  123.         }
  124.         else {
  125.             // Can't open file or file not found
  126.             int bySendCode = send(clientSock, (char*)&fileNotfound, sizeof(int), 0);
  127.             if (bySendCode == 0 || bySendCode == -1) {
  128.                 // error sending data - break loop
  129.                 clientClose = true;
  130.             }
  131.         }
  132.     } while (!clientClose);
  133.  
  134.     return 0;
  135. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement