diff --git a/WinChat/WinChat.vcxproj b/WinChat/WinChat.vcxproj index bda78f1..e9ce627 100644 --- a/WinChat/WinChat.vcxproj +++ b/WinChat/WinChat.vcxproj @@ -59,10 +59,13 @@ true stdcpp20 true + Use + pch.h Console true + ws2_32.lib;%(AdditionalDependencies) PreBuild.bat @@ -78,6 +81,8 @@ true stdcpp20 true + Use + pch.h Windows @@ -85,6 +90,7 @@ true true mainCRTStartup + ws2_32.lib;%(AdditionalDependencies) PreBuild.bat @@ -94,11 +100,22 @@ + + Create + + + Create + + + + + + diff --git a/WinChat/src/Application.cpp b/WinChat/src/Application.cpp index b9f8d63..ebcd8a4 100644 --- a/WinChat/src/Application.cpp +++ b/WinChat/src/Application.cpp @@ -1,10 +1,6 @@ +#include "pch.h" #include "Application.h" -#include -#include - -#include - #include "../resource.h" #include "Chat.h" @@ -33,7 +29,10 @@ namespace wc { } void Application::run() { - //First, run the main dialog to get needed input... + //First, start a thread to listen for incoming connections... + std::thread listenThread(&Application::startListen, this); + + //Then, run the main dialog to get needed input... INT_PTR result = NULL; MainDlgInput* input = new MainDlgInput{ this, -1, -1 }; while (result = DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOGMAIN), nullptr, (DLGPROC)mainDlgProc, reinterpret_cast(input))) { @@ -50,6 +49,76 @@ namespace wc { //And repeat until the user exits from the main dialog. input = new MainDlgInput{ this, x, y }; } + + listenThread.join(); + } + + void Application::startListen() { + WSADATA data = { }; + if (WSAStartup(MAKEWORD(2, 2), &data) != 0) { + std::cerr << std::format("Error: could not initialize WinSock 2!\n"); + std::exit(1); + } + + if (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2) { + std::cerr << std::format("Error: WinSock version 2.2 not available!\n"); + std::exit(1); + } + + addrinfo hints = { }; + addrinfo* hostInfo = nullptr; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + getaddrinfo(nullptr, "9430", &hints, &hostInfo); + + SOCKET sock = socket(hostInfo->ai_family, hostInfo->ai_socktype, hostInfo->ai_protocol); + if (sock == INVALID_SOCKET) { + std::cerr << std::format("Error: could not create network socket!\n"); + std::exit(1); + } + + if (bind(sock, hostInfo->ai_addr, static_cast(hostInfo->ai_addrlen)) != 0) { + std::cerr << std::format("Error: could not bind network socket!\n"); + std::exit(1); + } + + freeaddrinfo(hostInfo); + listen(sock, 1); + + sockaddr_storage remoteAddr = { }; + int remoteSize = sizeof(remoteAddr); + SOCKET conSock = accept(sock, reinterpret_cast(&remoteAddr), &remoteSize); + if (conSock == INVALID_SOCKET) { + std::cerr << std::format("Error: could not accept connection!\n");; + std::exit(1); + } + + std::string remoteStr; + remoteStr.resize(INET6_ADDRSTRLEN); + void* addrLocation = nullptr; + if (remoteAddr.ss_family == AF_INET) { + addrLocation = reinterpret_cast(&reinterpret_cast(&remoteAddr)->sin_addr); + } + else if (remoteAddr.ss_family = AF_INET6) { + addrLocation = reinterpret_cast(&reinterpret_cast(&remoteAddr)->sin6_addr); + } + inet_ntop(remoteAddr.ss_family, addrLocation, remoteStr.data(), INET6_ADDRSTRLEN); + std::cout << std::format("Connected to: {}\n", remoteStr); + + std::string buf(1000, 0); + + int bytesRecvd = 1; + while (bytesRecvd = recv(conSock, buf.data(), 1000, 0)) { + buf.resize(bytesRecvd); + std::cout << std::format("Remote: {}\n", buf); + buf.resize(1000); + } + + closesocket(conSock); + + closesocket(sock); + WSACleanup(); } BOOL CALLBACK Application::mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) { diff --git a/WinChat/src/Application.h b/WinChat/src/Application.h index f571e16..e4482cb 100644 --- a/WinChat/src/Application.h +++ b/WinChat/src/Application.h @@ -12,7 +12,7 @@ namespace wc { ~Application(); private: - + void startListen(); static BOOL CALLBACK mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam); const std::wstring m_appName; diff --git a/WinChat/src/Chat.cpp b/WinChat/src/Chat.cpp index b87c2f3..0d612a1 100644 --- a/WinChat/src/Chat.cpp +++ b/WinChat/src/Chat.cpp @@ -1,14 +1,43 @@ +#include "pch.h" #include "Chat.h" -#include +#include "StrConv.h" namespace wc { - Chat::Chat(std::wstring address, std::wstring screenname) { - MessageBox(nullptr, std::format(L"Address: {}\nScreen Name: {}", address, screenname).c_str(), L"Alert", MB_OK); + Chat::Chat(std::wstring address, std::wstring screenname) + : m_address(address) + , m_screenname(screenname) + { + } void Chat::run() { + addrinfo hints = { }; + addrinfo* destInfo = nullptr; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + getaddrinfo(toStr(m_address).c_str(), "9430", &hints, &destInfo); + SOCKET sock = socket(destInfo->ai_family, destInfo->ai_socktype, destInfo->ai_protocol); + if (sock == INVALID_SOCKET) { + std::cerr << std::format("Error: could not create network socket!\n"); + std::exit(1); + } + + if (connect(sock, destInfo->ai_addr, static_cast(destInfo->ai_addrlen)) != 0) { + std::cerr << std::format("Error: could not connect to destination!\n"); + std::exit(1); + } + + freeaddrinfo(destInfo); + + std::string data; + while (data != "end") { + std::getline(std::cin, data); + send(sock, data.data(), static_cast(data.size()), 0); + } + + closesocket(sock); } Chat::~Chat() { diff --git a/WinChat/src/Chat.h b/WinChat/src/Chat.h index 14fc9f6..00cbec4 100644 --- a/WinChat/src/Chat.h +++ b/WinChat/src/Chat.h @@ -12,6 +12,7 @@ namespace wc { ~Chat(); private: - + const std::wstring m_address; + const std::wstring m_screenname; }; } \ No newline at end of file diff --git a/WinChat/src/StrConv.cpp b/WinChat/src/StrConv.cpp new file mode 100644 index 0000000..de957db --- /dev/null +++ b/WinChat/src/StrConv.cpp @@ -0,0 +1,16 @@ +#include "pch.h" +#include "StrConv.h" + +namespace wc { + std::string toStr(const std::wstring& in) { + std::string out; + out.resize(in.size() + 1); + size_t tempSize = 0; + wcstombs_s(&tempSize, out.data(), out.size(), in.c_str(), out.size()); + return out; + } + + std::wstring toWideStr(const std::string& in){ + return std::wstring(in.begin(), in.end()); + } +} \ No newline at end of file diff --git a/WinChat/src/StrConv.h b/WinChat/src/StrConv.h new file mode 100644 index 0000000..981e424 --- /dev/null +++ b/WinChat/src/StrConv.h @@ -0,0 +1,7 @@ +#pragma once +#include + +namespace wc { + std::string toStr(const std::wstring& in); + std::wstring toWideStr(const std::string& in); +} \ No newline at end of file diff --git a/WinChat/src/main.cpp b/WinChat/src/main.cpp index a5c8f3b..ca0047a 100644 --- a/WinChat/src/main.cpp +++ b/WinChat/src/main.cpp @@ -1,5 +1,4 @@ -#include - +#include "pch.h" #include "version.h" #include "Application.h" diff --git a/WinChat/src/pch.cpp b/WinChat/src/pch.cpp new file mode 100644 index 0000000..1730571 --- /dev/null +++ b/WinChat/src/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" \ No newline at end of file diff --git a/WinChat/src/pch.h b/WinChat/src/pch.h new file mode 100644 index 0000000..b6e077a --- /dev/null +++ b/WinChat/src/pch.h @@ -0,0 +1,13 @@ +#pragma once + +//STL +#include +#include +#include + +//Windows +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include \ No newline at end of file