Add basic sockets

This commit is contained in:
Grayson Riffe 2023-09-20 21:26:08 -05:00
parent 3599be9c61
commit cebbb1dc19
10 changed files with 165 additions and 13 deletions

View File

@ -59,10 +59,13 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
<PreBuildEvent> <PreBuildEvent>
<Command>PreBuild.bat</Command> <Command>PreBuild.bat</Command>
@ -78,6 +81,8 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -85,6 +90,7 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol> <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
<PreBuildEvent> <PreBuildEvent>
<Command>PreBuild.bat</Command> <Command>PreBuild.bat</Command>
@ -94,11 +100,22 @@
<ClCompile Include="src\Application.cpp" /> <ClCompile Include="src\Application.cpp" />
<ClCompile Include="src\Chat.cpp" /> <ClCompile Include="src\Chat.cpp" />
<ClCompile Include="src\main.cpp" /> <ClCompile Include="src\main.cpp" />
<ClCompile Include="src\pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PrecompiledHeaderFile>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="src\StrConv.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="src\Application.h" /> <ClInclude Include="src\Application.h" />
<ClInclude Include="src\Chat.h" /> <ClInclude Include="src\Chat.h" />
<ClInclude Include="src\pch.h" />
<ClInclude Include="src\StrConv.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="WinChat.rc" /> <ResourceCompile Include="WinChat.rc" />

View File

@ -1,10 +1,6 @@
#include "pch.h"
#include "Application.h" #include "Application.h"
#include <iostream>
#include <format>
#include <CommCtrl.h>
#include "../resource.h" #include "../resource.h"
#include "Chat.h" #include "Chat.h"
@ -33,7 +29,10 @@ namespace wc {
} }
void Application::run() { 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; INT_PTR result = NULL;
MainDlgInput* input = new MainDlgInput{ this, -1, -1 }; MainDlgInput* input = new MainDlgInput{ this, -1, -1 };
while (result = DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOGMAIN), nullptr, (DLGPROC)mainDlgProc, reinterpret_cast<LPARAM>(input))) { while (result = DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOGMAIN), nullptr, (DLGPROC)mainDlgProc, reinterpret_cast<LPARAM>(input))) {
@ -50,6 +49,76 @@ namespace wc {
//And repeat until the user exits from the main dialog. //And repeat until the user exits from the main dialog.
input = new MainDlgInput{ this, x, y }; 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<int>(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<sockaddr*>(&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<void*>(&reinterpret_cast<sockaddr_in*>(&remoteAddr)->sin_addr);
}
else if (remoteAddr.ss_family = AF_INET6) {
addrLocation = reinterpret_cast<void*>(&reinterpret_cast<sockaddr_in6*>(&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) { BOOL CALLBACK Application::mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) {

View File

@ -12,7 +12,7 @@ namespace wc {
~Application(); ~Application();
private: private:
void startListen();
static BOOL CALLBACK mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam); static BOOL CALLBACK mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam);
const std::wstring m_appName; const std::wstring m_appName;

View File

@ -1,14 +1,43 @@
#include "pch.h"
#include "Chat.h" #include "Chat.h"
#include <format> #include "StrConv.h"
namespace wc { namespace wc {
Chat::Chat(std::wstring address, std::wstring screenname) { Chat::Chat(std::wstring address, std::wstring screenname)
MessageBox(nullptr, std::format(L"Address: {}\nScreen Name: {}", address, screenname).c_str(), L"Alert", MB_OK); : m_address(address)
, m_screenname(screenname)
{
} }
void Chat::run() { 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<int>(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<int>(data.size()), 0);
}
closesocket(sock);
} }
Chat::~Chat() { Chat::~Chat() {

View File

@ -12,6 +12,7 @@ namespace wc {
~Chat(); ~Chat();
private: private:
const std::wstring m_address;
const std::wstring m_screenname;
}; };
} }

16
WinChat/src/StrConv.cpp Normal file
View File

@ -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());
}
}

7
WinChat/src/StrConv.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include <string>
namespace wc {
std::string toStr(const std::wstring& in);
std::wstring toWideStr(const std::string& in);
}

View File

@ -1,5 +1,4 @@
#include <iostream> #include "pch.h"
#include "version.h" #include "version.h"
#include "Application.h" #include "Application.h"

1
WinChat/src/pch.cpp Normal file
View File

@ -0,0 +1 @@
#include "pch.h"

13
WinChat/src/pch.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
//STL
#include <iostream>
#include <format>
#include <thread>
//Windows
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <CommCtrl.h>
#include <WinSock2.h>
#include <WS2tcpip.h>