Advertisement
skindervik

Simple WIN32 UDP Chat

Dec 1st, 2018
296
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.27 KB | None | 0 0
  1. #define WIN32_LEAN_AND_MEAN
  2. #pragma warning(disable:4996)
  3. #include <WS2tcpip.h>
  4. #include <windows.h>
  5. #include <string>
  6. #include <thread>
  7.  
  8. #pragma comment (lib, "ws2_32.lib")
  9.  
  10. HWND chat_field = nullptr;
  11. HWND send_field = nullptr;
  12. HWND send_button = nullptr;
  13. HWND IP_field = nullptr;
  14.  
  15. WSADATA data;
  16. WORD version = MAKEWORD(2, 2);
  17. sockaddr_in server;
  18. SOCKET out;
  19. SOCKET in;
  20.  
  21. std::string IP = "127.0.0.1";
  22. int PORT = 54000;
  23. int server_PORT = 54000;
  24.  
  25. std::string get_window_text(HWND name) {
  26.     int len = GetWindowTextLength(name) + 1;
  27.     char* text = new char[len];
  28.     GetWindowText(name, text, len);
  29.     return (std::string)text;
  30. }
  31.  
  32. std::string get_time() {
  33.     time_t rawtime;
  34.     struct tm * timeinfo;
  35.     char buffer[88];
  36.  
  37.     time(&rawtime);
  38.     timeinfo = localtime(&rawtime);
  39.  
  40.     strftime(buffer, sizeof(buffer), "-%d-%m-%Y %H:%M:%S-", timeinfo);
  41.  
  42.     return buffer;
  43. }
  44.  
  45. void display_msg(std::string msg) {
  46.     SendMessage(chat_field, EM_SETSEL, 0, -1);
  47.     SendMessage(chat_field, EM_SETSEL, -1, -1);
  48.     SendMessage(chat_field, EM_REPLACESEL, TRUE, (LPARAM)(msg + "\n").c_str());
  49. }
  50.  
  51. void start_server() {
  52.     in = socket(AF_INET, SOCK_DGRAM, 0);
  53.  
  54.     sockaddr_in serverHint;
  55.     serverHint.sin_addr.S_un.S_addr = ADDR_ANY; // Us any IP address available on the machine
  56.     serverHint.sin_family = AF_INET; // Address format is IPv4
  57.     serverHint.sin_port = htons(server_PORT); // Convert from little to big endian
  58.  
  59.     if (bind(in, (sockaddr*)&serverHint, sizeof(serverHint)) == SOCKET_ERROR)
  60.     {
  61.         display_msg("ERROR BINDING THE SOCKET");
  62.     }
  63.  
  64.     sockaddr_in client; // Use to hold the client information (port / ip address)
  65.  
  66.     int clientLength = sizeof(client); // The size of the client information
  67.  
  68.     char buf[INT16_MAX];
  69.  
  70.     int failed_times = 5;
  71.  
  72.     while (true)
  73.     {
  74.         ZeroMemory(&client, clientLength); // Clear the client structure
  75.         ZeroMemory(buf, 1024); // Clear the receive buffer
  76.  
  77.         int bytesIn = recvfrom(in, buf, 1024, 0, (sockaddr*)&client, &clientLength);
  78.         if (bytesIn == SOCKET_ERROR)
  79.         {
  80.             if (failed_times == 5) {
  81.                 display_msg("ERROR RECEIVING FROM CLIANT");
  82.                 failed_times = 0;
  83.             }
  84.  
  85.             failed_times++;
  86.  
  87.             using namespace std::chrono_literals;
  88.  
  89.             std::this_thread::sleep_for(1s);
  90.  
  91.             continue;
  92.         }
  93.         char clientIp[256]; // Create enough space to convert the address byte array
  94.         ZeroMemory(clientIp, 256); // to string of characters
  95.  
  96.         inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);
  97.  
  98.         display_msg((std::string)"MSG RECV. at " + get_time() + " from- " + clientIp + ": " + buf);
  99.  
  100.     }
  101. }
  102.  
  103.  
  104.  
  105. void send_msg() {
  106.     if (get_window_text(IP_field) != IP) {
  107.         IP = get_window_text(IP_field);
  108.         inet_pton(AF_INET, IP.c_str(), &server.sin_addr); // Convert from string to byte array
  109.     }
  110.  
  111.     std::string s = get_window_text(send_field);
  112.  
  113.     display_msg( (std::string)"MSG SENT. at " + get_time() + " to- " + get_window_text(IP_field) + ": " + s );
  114.    
  115.     int sendOk = sendto(out, s.c_str(), s.size() + 1, 0, (sockaddr*)&server, sizeof(server));
  116.     if (sendOk == SOCKET_ERROR)
  117.     {
  118.         display_msg("ERROR TRYING TO SEND");
  119.     }
  120.  
  121.     SetWindowText(send_field,"");
  122. }
  123.  
  124. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { //Window message processing
  125.  
  126.     switch (msg)
  127.     {
  128.     case WM_SIZE:
  129.     {
  130.         RECT rect;
  131.         if (GetWindowRect(hwnd, &rect))
  132.         {
  133.             int width = rect.right - rect.left;
  134.             int height = rect.bottom - rect.top;
  135.  
  136.             SetWindowPos(chat_field, 0, 0, 23, width-17, height-65-23, NULL);
  137.             SetWindowPos(send_field, 0, 0, height-65, width - 68, 40, NULL);
  138.             SetWindowPos(send_button, 0, width-66, height-62, 50, 20, NULL);
  139.         }
  140.     }
  141.         break;
  142.     case WM_COMMAND:
  143.        
  144.         switch (LOWORD(wParam)){
  145.  
  146.         case 2:{
  147.  
  148.             if (wParam == 83951618) {
  149.                 send_msg();
  150.             }
  151.         }
  152.         break;
  153.  
  154.         case 1:{
  155.             send_msg();
  156.         }
  157.         break;
  158.         }
  159.         break;
  160.     case WM_CREATE: {
  161.  
  162.         CreateWindow("STATIC", "SEND TO: ", WS_VISIBLE | WS_CHILD , 2, 3, 70, 17, hwnd, nullptr, nullptr, nullptr);
  163.  
  164.         IP_field = CreateWindow("EDIT", IP.c_str(), WS_VISIBLE | WS_CHILD | WS_BORDER, 70, 3, 200, 17, hwnd, nullptr, nullptr, nullptr);
  165.  
  166.         chat_field = CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL  | WS_BORDER | ES_READONLY, 0, 23, 518, 348, hwnd, nullptr, nullptr, nullptr);
  167.  
  168.         send_field = CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER | WS_HSCROLL | ES_MULTILINE, 0, 372, 450, 40, hwnd, (HMENU)2, nullptr, nullptr);
  169.    
  170.         send_button = CreateWindow("BUTTON", "SEND", WS_VISIBLE | WS_CHILD, 452, 373, 50, 20, hwnd, (HMENU)1, nullptr, nullptr);
  171.        
  172.         SetFocus(send_field);
  173.     }
  174.                     break;
  175.     case WM_DESTROY:
  176.         closesocket(out);
  177.         closesocket(in);
  178.         WSACleanup();
  179.         quick_exit(0);
  180.         break;
  181.     default:
  182.         return DefWindowProc(hwnd, msg, wParam, lParam);
  183.     }
  184.     return 0;
  185. }
  186.  
  187. int WinMain(_In_ HINSTANCE hInstance, _In_opt_  HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { //Entry Point
  188.  
  189.     UNREFERENCED_PARAMETER(hPrevInstance);
  190.     UNREFERENCED_PARAMETER(lpCmdLine);
  191.     UNREFERENCED_PARAMETER(nCmdShow);
  192.  
  193.     WNDCLASS window; //Create window class
  194.  
  195.     window.cbClsExtra = NULL;
  196.     window.cbWndExtra = NULL;
  197.     window.hbrBackground = (HBRUSH)(COLOR_WINDOW);
  198.     window.hCursor = LoadCursor(NULL, IDC_ARROW);
  199.     window.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  200.     window.hInstance = hInstance;
  201.     window.lpfnWndProc = WndProc;
  202.     window.lpszClassName = "just_window";
  203.     window.lpszMenuName = nullptr;
  204.     window.style = CS_HREDRAW | CS_VREDRAW;;
  205.  
  206.     RegisterClass(&window); //Register the defined window class
  207.  
  208.     CreateWindow("just_window", "Chat", WS_VISIBLE | WS_SYSMENU | WS_SIZEBOX | WS_MAXIMIZEBOX | WS_MINIMIZEBOX, 0, 0, 518, 435, nullptr, nullptr, hInstance, nullptr); //Create the defined window
  209.  
  210.     int wsOk = WSAStartup(version, &data);
  211.     if (wsOk != 0)
  212.     {
  213.         // Not ok! Get out quickly
  214.         display_msg("STARTING WINSOCK FAILED!");
  215.     }
  216.    
  217.     server.sin_family = AF_INET; // AF_INET = IPv4 addresses
  218.     server.sin_port = htons(PORT); // Little to big endian conversion
  219.     inet_pton(AF_INET, IP.c_str(), &server.sin_addr); // Convert from string to byte array
  220.  
  221.     out = socket(AF_INET, SOCK_DGRAM, 0);
  222.  
  223.     std::thread my_slave(start_server);
  224.  
  225.     MSG msg; //Create message class
  226.  
  227.     while (GetMessage(&msg, NULL, 0, 0)) { //Message loop, get message
  228.         TranslateMessage(&msg); //Read Message
  229.         DispatchMessage(&msg); //Send message to WndProc
  230.     }
  231.  
  232.     return (int)msg.wParam;
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement