Advertisement
Guest User

Untitled

a guest
Mar 24th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.60 KB | None | 0 0
  1. #include <windows.networking.sockets.h>
  2. #include <string>
  3. #include <iostream>
  4. #include <regex>
  5.  
  6. #pragma comment(lib, "Ws2_32.lib")
  7.  
  8. enum SocketType { CLIENT, SERVER };
  9. enum ConnectionType { TCP, UDP };
  10. const int DEFAULT_SIZE = 128;
  11.  
  12. class MySocket {
  13. char *Buffer = nullptr;
  14. SOCKET WelcomeSocket;
  15. SOCKET ConnectionSocket;
  16. sockaddr_in SvrAddr;
  17. sockaddr_in RespAddr;
  18. SocketType mySocket;
  19. std::string IPAddr = std::string();
  20. int Port = 0;
  21. ConnectionType connectionType;
  22. bool bConnect = false;
  23. int MaxSize = DEFAULT_SIZE;
  24. public:
  25. MySocket(SocketType socketType, std::string ip, unsigned int port, ConnectionType connectionType, unsigned int size) {
  26. this->Buffer = new char[
  27. this->MaxSize = (size > 0 && size < 256 ? size : DEFAULT_SIZE)
  28. ];
  29.  
  30. bool failedToConstruct = (!(
  31. this->SetType(socketType) &&
  32. this->SetIPAddr(ip) &&
  33. this->SetPortNum(port) &&
  34. (this->connectionType = connectionType) >= 0 &&
  35. StartWSA() == 0
  36. ));
  37.  
  38. if (failedToConstruct)
  39. throw "Failed to construct socket"; // SetSafeEmptyState();
  40.  
  41. // "Note that the constructor should put servers in conditions to either
  42. // accept connections (if TCP), or to receive messages (if UDP)."
  43. if (connectionType == TCP) {
  44. this->ConnectionSocket = this->initialize_tcp_socket();
  45. if (mySocket == SERVER) {
  46. this->WelcomeSocket = this->initialize_tcp_socket();
  47. if (!this->bind_tcp_socket() || !this->listen_tcp_socket()) {
  48. closesocket(this->WelcomeSocket);
  49. WSACleanup();
  50. throw "Failed to initialize TCP server socket";
  51. }
  52. }
  53. }
  54. else /* UDP */ {
  55. // TODO initialize UDP connection socket
  56. // (Although, it looks like SetupUDP() is currently handling that...)
  57. if (mySocket == SERVER) {
  58. // TODO place UDP_Server "in conditions [...] to receive messages"
  59. // (SetupUDP() also looks to be currently handling that logic)
  60. }
  61. }
  62. }
  63.  
  64. ~MySocket() {
  65. delete[] Buffer;
  66. if (!(this->connectionType == TCP ? this->DisconnectTCP() : this->TerminateUDP()))
  67. throw "Socket failed to properly disconnect/terminate before destruction";
  68. };
  69.  
  70. bool StartWSA() { // which member functions are responsible for calling this?
  71. WSADATA wsaData;
  72. return WSAStartup(MAKEWORD(2, 2), &wsaData) == 0;
  73. };
  74.  
  75. bool ConnectTCP() {
  76. if (this->connectionType != TCP) return false;
  77.  
  78. if (this->mySocket == CLIENT)
  79. return connect_to_tcp_server();
  80. else /* SERVER */
  81. return accept_tcp_connection();
  82. }
  83.  
  84. bool connect_to_tcp_server() {
  85. SvrAddr.sin_family = AF_INET;
  86. SvrAddr.sin_port = htons(this->GetPort());
  87. SvrAddr.sin_addr.s_addr = inet_addr(this->GetIPAddr().c_str());
  88. return connect(this->ConnectionSocket, (struct sockaddr *)&SvrAddr, sizeof(SvrAddr)) != SOCKET_ERROR;
  89. }
  90.  
  91. SOCKET initialize_tcp_socket() {
  92. SOCKET LocalSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  93. if (LocalSocket == INVALID_SOCKET) {
  94. WSACleanup();
  95. throw "TCP socket failed to initialize";
  96. }
  97. return LocalSocket;
  98. }
  99.  
  100. bool bind_tcp_socket() {
  101. SvrAddr.sin_family = AF_INET;
  102. SvrAddr.sin_port = htons(this->GetPort());
  103. SvrAddr.sin_addr.s_addr = inet_addr(this->GetIPAddr().c_str());
  104. return ::bind(this->WelcomeSocket, (struct sockaddr *)&SvrAddr, sizeof(SvrAddr)) != SOCKET_ERROR;
  105. }
  106.  
  107. bool listen_tcp_socket() {
  108. return listen(this->WelcomeSocket, 1) != SOCKET_ERROR;
  109. }
  110.  
  111. bool accept_tcp_connection() {
  112. return (ConnectionSocket = accept(this->WelcomeSocket, NULL, NULL)) != SOCKET_ERROR;
  113. }
  114.  
  115. bool DisconnectTCP() {
  116. if (this->connectionType != TCP) return false;
  117.  
  118. bool success = closesocket(this->ConnectionSocket) == 0;
  119.  
  120. if (this->mySocket == SERVER)
  121. success = success && closesocket(this->WelcomeSocket) == 0;
  122.  
  123. // success = success && (any other considerations)
  124.  
  125. return success && WSACleanup() == 0 && this->SetSafeEmptyState();
  126. }
  127.  
  128. bool SetupUDP() { // minor adjustments
  129. if (this->connectionType == UDP) {
  130. this->ConnectionSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  131. if (this->ConnectionSocket == INVALID_SOCKET) {
  132. WSACleanup();
  133. return false;
  134. }
  135. else {
  136. if (this->mySocket == CLIENT) {
  137. SvrAddr.sin_family = AF_INET;
  138. SvrAddr.sin_port = htons(this->GetPort());
  139. SvrAddr.sin_addr.s_addr = inet_addr(this->GetIPAddr().c_str());
  140. return true;
  141. }
  142. else {
  143. SvrAddr.sin_family = AF_INET;
  144. SvrAddr.sin_addr.s_addr = INADDR_ANY;
  145. SvrAddr.sin_port = htons(27000);
  146. if (::bind(this->ConnectionSocket, (struct sockaddr *)&SvrAddr, sizeof(SvrAddr)) == SOCKET_ERROR)
  147. {
  148. closesocket(this->ConnectionSocket);
  149. WSACleanup();
  150. return false;
  151. }
  152. }
  153. }
  154. }
  155. else /* TCP */
  156. return false;
  157. }
  158.  
  159. bool TerminateUDP() { // modified to mirror DisconnectTCP()
  160. if (this->connectionType != UDP) return false;
  161.  
  162. bool success = closesocket(this->ConnectionSocket) == 0;
  163.  
  164. // success = success && (any other considerations)
  165.  
  166. return success && WSACleanup() == 0 && this->SetSafeEmptyState();
  167. }
  168.  
  169. int SendData(const char* buff, int len) {
  170. if (this->connectionType == TCP)
  171. return send(this->ConnectionSocket, buff, len, 0);
  172. else /* UDP */
  173. return -1/*sendto(...)*/;
  174. }
  175.  
  176. int GetData(char*) {
  177. memset(this->Buffer, 0, this->MaxSize);
  178. if (this->connectionType == TCP)
  179. return recv(this->ConnectionSocket, this->Buffer, this->MaxSize, 0);
  180. else /* UDP */
  181. return -1/*recvfrom(...)*/;
  182. }
  183.  
  184. std::string GetIPAddr() { return IPAddr; }
  185.  
  186. bool SetIPAddr(std::string ip) {
  187.  
  188. bool validIPv4 = true/*false*/;
  189.  
  190. // https://www.regular-expressions.info/stdregex.html
  191. // https://www.tutorialspoint.com/cpp_standard_library/cpp_regex_match.htm
  192. /* REGEX NOT YET TESTED */
  193. //try {
  194. // 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]?)$");
  195. // validIPv4 = std::regex_match(ip, re);
  196. //}
  197. //catch (std::regex_error& e) {
  198. // exit('r'); // Syntax error in the regular expression
  199. //}
  200.  
  201. return !(this->bConnect || this->Port) ? validIPv4 && (this->IPAddr = ip) == ip : false;
  202. }
  203.  
  204. bool SetPortNum(int port) {
  205. return !(this->bConnect || this->Port) ? port > 0 && (this->Port = port) == port : false;
  206. }
  207.  
  208. int GetPort() { return this->Port; }
  209.  
  210. SocketType GetType() { return this->mySocket; }
  211.  
  212. bool SetType(SocketType socketType) {
  213. return !(this->bConnect || this->Port) ? (this->mySocket = socketType) == socketType : false;
  214. }
  215.  
  216. bool SetSafeEmptyState() {
  217. delete[] this->Buffer;
  218. this->Buffer = nullptr;
  219. this->MaxSize = DEFAULT_SIZE;
  220. this->SetIPAddr(std::string());
  221. this->SetPortNum(0);
  222. this->bConnect = false;
  223. return true;
  224. }
  225. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement