Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.networking.sockets.h>
- #include <string>
- #include <iostream>
- #include <regex>
- #pragma comment(lib, "Ws2_32.lib")
- enum SocketType { CLIENT, SERVER };
- enum ConnectionType { TCP, UDP };
- const int DEFAULT_SIZE = 128;
- class MySocket {
- char *Buffer = nullptr;
- SOCKET WelcomeSocket;
- SOCKET ConnectionSocket;
- sockaddr_in SvrAddr;
- sockaddr_in RespAddr;
- SocketType mySocket;
- std::string IPAddr = std::string();
- int Port = 0;
- ConnectionType connectionType;
- bool bConnect = false;
- int MaxSize = DEFAULT_SIZE;
- public:
- MySocket(SocketType socketType, std::string ip, unsigned int port, ConnectionType connectionType, unsigned int size) {
- this->Buffer = new char[
- this->MaxSize = (size > 0 && size < 256 ? size : DEFAULT_SIZE)
- ];
- bool failedToConstruct = (!(
- this->SetType(socketType) &&
- this->SetIPAddr(ip) &&
- this->SetPortNum(port) &&
- (this->connectionType = connectionType) >= 0 &&
- StartWSA() == 0
- ));
- if (failedToConstruct)
- throw "Failed to construct socket"; // SetSafeEmptyState();
- // "Note that the constructor should put servers in conditions to either
- // accept connections (if TCP), or to receive messages (if UDP)."
- if (connectionType == TCP) {
- this->ConnectionSocket = this->initialize_tcp_socket();
- if (mySocket == SERVER) {
- this->WelcomeSocket = this->initialize_tcp_socket();
- if (!this->bind_tcp_socket() || !this->listen_tcp_socket()) {
- closesocket(this->WelcomeSocket);
- WSACleanup();
- throw "Failed to initialize TCP server socket";
- }
- }
- }
- else /* UDP */ {
- // TODO initialize UDP connection socket
- // (Although, it looks like SetupUDP() is currently handling that...)
- if (mySocket == SERVER) {
- // TODO place UDP_Server "in conditions [...] to receive messages"
- // (SetupUDP() also looks to be currently handling that logic)
- }
- }
- }
- ~MySocket() {
- delete[] Buffer;
- if (!(this->connectionType == TCP ? this->DisconnectTCP() : this->TerminateUDP()))
- throw "Socket failed to properly disconnect/terminate before destruction";
- };
- bool StartWSA() { // which member functions are responsible for calling this?
- WSADATA wsaData;
- return WSAStartup(MAKEWORD(2, 2), &wsaData) == 0;
- };
- bool ConnectTCP() {
- if (this->connectionType != TCP) return false;
- if (this->mySocket == CLIENT)
- return connect_to_tcp_server();
- else /* SERVER */
- return accept_tcp_connection();
- }
- bool connect_to_tcp_server() {
- SvrAddr.sin_family = AF_INET;
- SvrAddr.sin_port = htons(this->GetPort());
- SvrAddr.sin_addr.s_addr = inet_addr(this->GetIPAddr().c_str());
- return connect(this->ConnectionSocket, (struct sockaddr *)&SvrAddr, sizeof(SvrAddr)) != SOCKET_ERROR;
- }
- SOCKET initialize_tcp_socket() {
- SOCKET LocalSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (LocalSocket == INVALID_SOCKET) {
- WSACleanup();
- throw "TCP socket failed to initialize";
- }
- return LocalSocket;
- }
- bool bind_tcp_socket() {
- SvrAddr.sin_family = AF_INET;
- SvrAddr.sin_port = htons(this->GetPort());
- SvrAddr.sin_addr.s_addr = inet_addr(this->GetIPAddr().c_str());
- return ::bind(this->WelcomeSocket, (struct sockaddr *)&SvrAddr, sizeof(SvrAddr)) != SOCKET_ERROR;
- }
- bool listen_tcp_socket() {
- return listen(this->WelcomeSocket, 1) != SOCKET_ERROR;
- }
- bool accept_tcp_connection() {
- return (ConnectionSocket = accept(this->WelcomeSocket, NULL, NULL)) != SOCKET_ERROR;
- }
- bool DisconnectTCP() {
- if (this->connectionType != TCP) return false;
- bool success = closesocket(this->ConnectionSocket) == 0;
- if (this->mySocket == SERVER)
- success = success && closesocket(this->WelcomeSocket) == 0;
- // success = success && (any other considerations)
- return success && WSACleanup() == 0 && this->SetSafeEmptyState();
- }
- bool SetupUDP() { // minor adjustments
- if (this->connectionType == UDP) {
- this->ConnectionSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (this->ConnectionSocket == INVALID_SOCKET) {
- WSACleanup();
- return false;
- }
- else {
- if (this->mySocket == CLIENT) {
- SvrAddr.sin_family = AF_INET;
- SvrAddr.sin_port = htons(this->GetPort());
- SvrAddr.sin_addr.s_addr = inet_addr(this->GetIPAddr().c_str());
- return true;
- }
- else {
- SvrAddr.sin_family = AF_INET;
- SvrAddr.sin_addr.s_addr = INADDR_ANY;
- SvrAddr.sin_port = htons(27000);
- if (::bind(this->ConnectionSocket, (struct sockaddr *)&SvrAddr, sizeof(SvrAddr)) == SOCKET_ERROR)
- {
- closesocket(this->ConnectionSocket);
- WSACleanup();
- return false;
- }
- }
- }
- }
- else /* TCP */
- return false;
- }
- bool TerminateUDP() { // modified to mirror DisconnectTCP()
- if (this->connectionType != UDP) return false;
- bool success = closesocket(this->ConnectionSocket) == 0;
- // success = success && (any other considerations)
- return success && WSACleanup() == 0 && this->SetSafeEmptyState();
- }
- int SendData(const char* buff, int len) {
- if (this->connectionType == TCP)
- return send(this->ConnectionSocket, buff, len, 0);
- else /* UDP */
- return -1/*sendto(...)*/;
- }
- int GetData(char*) {
- memset(this->Buffer, 0, this->MaxSize);
- if (this->connectionType == TCP)
- return recv(this->ConnectionSocket, this->Buffer, this->MaxSize, 0);
- else /* UDP */
- return -1/*recvfrom(...)*/;
- }
- std::string GetIPAddr() { return IPAddr; }
- bool SetIPAddr(std::string ip) {
- bool validIPv4 = true/*false*/;
- // https://www.regular-expressions.info/stdregex.html
- // https://www.tutorialspoint.com/cpp_standard_library/cpp_regex_match.htm
- /* REGEX NOT YET TESTED */
- //try {
- // std::regex re("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
- // validIPv4 = std::regex_match(ip, re);
- //}
- //catch (std::regex_error& e) {
- // exit('r'); // Syntax error in the regular expression
- //}
- return !(this->bConnect || this->Port) ? validIPv4 && (this->IPAddr = ip) == ip : false;
- }
- bool SetPortNum(int port) {
- return !(this->bConnect || this->Port) ? port > 0 && (this->Port = port) == port : false;
- }
- int GetPort() { return this->Port; }
- SocketType GetType() { return this->mySocket; }
- bool SetType(SocketType socketType) {
- return !(this->bConnect || this->Port) ? (this->mySocket = socketType) == socketType : false;
- }
- bool SetSafeEmptyState() {
- delete[] this->Buffer;
- this->Buffer = nullptr;
- this->MaxSize = DEFAULT_SIZE;
- this->SetIPAddr(std::string());
- this->SetPortNum(0);
- this->bConnect = false;
- return true;
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement