Mihailo21

PeteTCPServer

Nov 21st, 2023
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.05 KB | None | 0 0
  1. #define WIN32_LEAN_AND_MEAN
  2.  
  3. #include <windows.h>
  4. #include <winsock2.h>
  5. #include <ws2tcpip.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include "conio.h"
  9.  
  10. #pragma comment (lib, "Ws2_32.lib")
  11. #pragma comment (lib, "Mswsock.lib")
  12. #pragma comment (lib, "AdvApi32.lib")
  13.  
  14. #pragma pack(1)
  15.  
  16. #define SERVER_PORT 27016
  17. #define BUFFER_SIZE 256
  18. #define MAX_CLIENTS 3
  19.  
  20.  
  21. struct studentInfo{
  22.     char ime [15];
  23.     char prezime [20];
  24.     short poeni;
  25. };
  26.  
  27. // TCP server that use non-blocking sockets
  28. int main()
  29. {
  30.     // Socket used for listening for new clients
  31.     SOCKET listenSocket = INVALID_SOCKET;
  32.  
  33.     // Sockets used for communication with client
  34.     SOCKET clientSockets[MAX_CLIENTS];
  35.     short lastIndex = 0;
  36.  
  37.     // Variable used to store function return value
  38.     int iResult;
  39.  
  40.     // Buffer used for storing incoming data
  41.     char dataBuffer[BUFFER_SIZE];
  42.  
  43.     // WSADATA data structure that is to receive details of the Windows Sockets implementation
  44.     WSADATA wsaData;
  45.  
  46.     // Initialize windows sockets library for this process
  47.     if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
  48.     {
  49.         printf("WSAStartup failed with error: %d\n", WSAGetLastError());
  50.         return 1;
  51.     }
  52.  
  53.     // Initialize serverAddress structure used by bind
  54.     sockaddr_in serverAddress;
  55.     memset((char*)&serverAddress,0,sizeof(serverAddress));
  56.     serverAddress.sin_family = AF_INET;             // IPv4 address family
  57.     serverAddress.sin_addr.s_addr = INADDR_ANY;     // Use all available addresses
  58.     serverAddress.sin_port = htons(SERVER_PORT);    // Use specific port
  59.  
  60.     //initialise all client_socket[] to 0 so not checked
  61.     memset(clientSockets, 0, MAX_CLIENTS * sizeof(SOCKET));
  62.  
  63.     // Create a SOCKET for connecting to server
  64.     listenSocket = socket(AF_INET,      // IPv4 address family
  65.         SOCK_STREAM,  // Stream socket
  66.         IPPROTO_TCP); // TCP protocol
  67.  
  68.     // Check if socket is successfully created
  69.     if (listenSocket == INVALID_SOCKET)
  70.     {
  71.         printf("socket failed with error: %ld\n", WSAGetLastError());
  72.         WSACleanup();
  73.         return 1;
  74.     }
  75.  
  76.     // Setup the TCP listening socket - bind port number and local address to socket
  77.     iResult = bind(listenSocket,(struct sockaddr*) &serverAddress,sizeof(serverAddress));
  78.  
  79.     // Check if socket is successfully binded to address and port from sockaddr_in structure
  80.     if (iResult == SOCKET_ERROR)
  81.     {
  82.         printf("bind failed with error: %d\n", WSAGetLastError());
  83.         closesocket(listenSocket);
  84.         WSACleanup();
  85.         return 1;
  86.     }
  87.  
  88.     //// All connections are by default accepted by protocol stek if socket is in listening mode.
  89.     //// With SO_CONDITIONAL_ACCEPT parameter set to true, connections will not be accepted by default
  90.     bool bOptVal = true;
  91.     int bOptLen = sizeof (bool);
  92.     iResult = setsockopt(listenSocket, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char *) &bOptVal, bOptLen);
  93.        if (iResult == SOCKET_ERROR) {
  94.            printf("setsockopt for SO_CONDITIONAL_ACCEPT failed with error: %u\n", WSAGetLastError());
  95.     }
  96.  
  97.     unsigned long  mode = 1;
  98.     if (ioctlsocket(listenSocket, FIONBIO, &mode) != 0)
  99.         printf("ioctlsocket failed with error.");
  100.  
  101.     // Set listenSocket in listening mode
  102.     iResult = listen(listenSocket, SOMAXCONN);
  103.     if (iResult == SOCKET_ERROR)
  104.     {
  105.         printf("listen failed with error: %d\n", WSAGetLastError());
  106.         closesocket(listenSocket);
  107.         WSACleanup();
  108.         return 1;
  109.     }
  110.  
  111.     printf("Server socket is set to listening mode. Waiting for new connection requests.\n");
  112.  
  113.     // set of socket descriptors
  114.     fd_set readfds;
  115.  
  116.     // timeout for select function
  117.     timeval timeVal;
  118.     timeVal.tv_sec = 1;
  119.     timeVal.tv_usec = 0;
  120.    
  121.    
  122.     studentInfo *student;
  123.  
  124.     while(true)
  125.     {
  126.         // initialize socket set
  127.         FD_ZERO(&readfds);
  128.  
  129.         // add server's socket and clients' sockets to set
  130.         if (lastIndex != MAX_CLIENTS)
  131.         {
  132.             FD_SET(listenSocket, &readfds);
  133.         }
  134.  
  135.         for ( int i = 0 ; i < lastIndex ; i++)
  136.         {
  137.             FD_SET(clientSockets[i], &readfds);
  138.         }
  139.  
  140.         // wait for events on set
  141.         int selectResult = select( 0 , &readfds , NULL , NULL , &timeVal);
  142.  
  143.         if (selectResult == SOCKET_ERROR)
  144.         {
  145.             printf("Select failed with error: %d\n", WSAGetLastError());
  146.             closesocket(listenSocket);
  147.             WSACleanup();
  148.             return 1;
  149.         }
  150.         else if(selectResult == 0) // timeout expired
  151.         {
  152.             if(_kbhit()) //check if some key is pressed
  153.             {
  154.                 getch();
  155.                 printf("Primena racunarskih mreza u infrstrukturnim sistemima 2019/2020\n");
  156.             }
  157.             continue;
  158.         }
  159.         else if (FD_ISSET(listenSocket, &readfds))
  160.         {
  161.             // Struct for information about connected client
  162.             sockaddr_in clientAddr;
  163.             int clientAddrSize = sizeof(struct sockaddr_in);
  164.  
  165.             // New connection request is received. Add new socket in array on first free position.
  166.             clientSockets[lastIndex] = accept(listenSocket, (struct sockaddr *)&clientAddr, &clientAddrSize);
  167.  
  168.             if (clientSockets[lastIndex] == INVALID_SOCKET)
  169.             {
  170.                 if (WSAGetLastError() == WSAECONNRESET)
  171.                 {
  172.                     printf("accept failed, because timeout for client request has expired.\n");
  173.                 }
  174.                 else
  175.                 {
  176.                     printf("accept failed with error: %d\n", WSAGetLastError());
  177.                 }
  178.             }
  179.             else
  180.             {
  181.                 if (ioctlsocket(clientSockets[lastIndex], FIONBIO, &mode) != 0)
  182.                 {
  183.                     printf("ioctlsocket failed with error.");
  184.                     continue;
  185.                 }
  186.                 lastIndex ++;
  187.                 printf("New client request accepted (%d). Client address: %s : %d\n", lastIndex, inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));
  188.  
  189.             }
  190.         }
  191.         else
  192.         {
  193.  
  194.             // Check if new message is received from connected clients
  195.             for (int i = 0; i < lastIndex ; i++)
  196.             {
  197.                 // Check if new message is received from client on position "i"
  198.                 if (FD_ISSET(clientSockets[i], &readfds))
  199.                 {
  200.                     iResult = recv(clientSockets[i], dataBuffer, BUFFER_SIZE, 0);
  201.  
  202.                     if (iResult > 0)
  203.                     {
  204.                         dataBuffer[iResult] = '\0';
  205.                         printf("Message received from client (%d):\n", i+1);
  206.                        
  207.                         //primljenoj poruci u memoriji pristupiti preko pokazivaca tipa (studentInfo *)
  208.                         //jer znamo format u kom je poruka poslata a to je struct studentInfo
  209.                         student=(studentInfo *)dataBuffer;
  210.  
  211.                         printf("Ime i prezime: %s %s  \n", student->ime, student->prezime);
  212.  
  213.                         printf("Poeni studenta: %d  \n", ntohs(student->poeni));
  214.                         printf("_______________________________  \n");
  215.  
  216.                        
  217.                     }
  218.                     else if (iResult == 0)
  219.                     {
  220.                         // connection was closed gracefully
  221.                         printf("Connection with client (%d) closed.\n", i+1);
  222.                         closesocket(clientSockets[i]);
  223.  
  224.                         // sort array and clean last place
  225.                         for (int j = i; j < lastIndex-1; j++)
  226.                         {
  227.                             clientSockets[j] = clientSockets[j+1];
  228.                         }
  229.                         clientSockets[lastIndex-1] = 0;
  230.  
  231.                         lastIndex--;
  232.                     }
  233.                     else
  234.                     {
  235.                         // there was an error during recv
  236.                         printf("recv failed with error: %d\n", WSAGetLastError());
  237.                         closesocket(clientSockets[i]);
  238.  
  239.                         // sort array and clean last place
  240.                         for (int j = i; j < lastIndex-1; j++)
  241.                         {
  242.                             clientSockets[j] = clientSockets[j+1];
  243.                         }
  244.                         clientSockets[lastIndex-1] = 0;
  245.  
  246.                         lastIndex--;
  247.                     }
  248.                 }
  249.             }
  250.         }
  251.     }
  252.  
  253.     //Close listen and accepted sockets
  254.     closesocket(listenSocket);
  255.  
  256.     // Deinitialize WSA library
  257.     WSACleanup();
  258.  
  259.     return 0;
  260. }
  261.  
Add Comment
Please, Sign In to add comment