Pārlūkot izejas kodu

Add windows support

manuel5975p 6 gadi atpakaļ
vecāks
revīzija
319767e73e
1 mainītis faili ar 235 papildinājumiem un 0 dzēšanām
  1. 235 0
      socketio_win32.cpp

+ 235 - 0
socketio_win32.cpp

@@ -0,0 +1,235 @@
+#include "socketio.hpp"
+#include <stdio.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <string>
+#include <cstring>
+#include <vector>
+#include <iostream>
+#pragma comment(lib, "ws2_32.lib")
+using std::size_t;
+struct socket_exception : public std::exception{
+	std::string msg;
+	socket_exception(std::string&& _msg){
+		msg = std::move(_msg);
+	}
+	socket_exception(const std::string& _msg){
+		msg = _msg;
+	}
+	socket_exception(const char* _msg){
+		msg = std::string(_msg);
+	}
+	const char* what() const throw (){
+		//return "asdasdsa";
+    	return msg.length() == 0 ? "Connection creation failure" : msg.c_str();
+    }
+};
+template<typename T>
+std::ostream& operator<<(std::ostream& out, std::vector<T> o){
+	out << "[";
+	for(unsigned int i = 0;i < o.size();i++){
+		if(o[i] == '\r')continue;
+		out << o[i];
+		if(i < o.size() - 1)
+			out << ", ";
+	}
+	return out << "]";
+}
+template<>
+std::ostream& operator<< <char>(std::ostream& out, std::vector<char> o){
+	for(unsigned int i = 0;i < o.size();i++){
+		if(o[i])
+		out << o[i];
+	}
+	return out;
+}
+std::string GetLastErrorAsString()
+{
+    //Get the error message, if any.
+    DWORD errorMessageID = ::GetLastError();
+    if(errorMessageID == 0)
+        return std::string();
+
+    LPSTR messageBuffer = nullptr;
+    size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+                                 NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
+
+    std::string message(messageBuffer, size);
+
+    //Free the buffer.
+    LocalFree(messageBuffer);
+
+    return message;
+}
+
+class cppsocket{
+	private:
+	WSADATA wsa;
+	SOCKET s;
+	std::vector<char> buffer;
+	public:
+	static const int buffersize = 1024;
+	cppsocket(WSADATA d, SOCKET _s){
+		s = _s;
+		wsa = d;
+		buffer = std::vector<char>(buffersize);
+	}
+	cppsocket(const std::string& addr, unsigned short PORT){
+		struct sockaddr_in server;
+		buffer = std::vector<char>(buffersize);
+		int recv_size;
+		
+		if (WSAStartup(MAKEWORD(2,2),&wsa) != 0){
+			throw socket_exception(std::string("Socket creation error: ") + GetLastErrorAsString());
+		}
+		
+		if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET){
+			throw socket_exception(std::string("Socket creation error: ") + GetLastErrorAsString());
+		}
+		
+		server.sin_addr.s_addr = inet_addr(addr.c_str());
+		server.sin_family = AF_INET;
+		server.sin_port = htons(PORT);
+
+		if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0){
+			throw socket_exception(std::string("Could not connect to host: ") + GetLastErrorAsString());
+		}
+	}
+	void write(const std::string& message){
+		std::vector<char> msg(message.c_str(), message.c_str() + message.size());
+		write(msg);
+	}
+	void write(const std::vector<char>& message){
+		for(size_t i = 0;i < message.size();i += buffersize){
+			char cs[buffersize + 1] = {0};
+			std::memcpy(cs, message.data() + i,buffersize);
+			if((i + buffersize) < message.size()){
+				cs[buffersize] = 'c';
+				if(send(s, cs, buffersize + 1, 0) < 0){
+					throw socket_exception(std::string("Couldn't write to peer: ") + GetLastErrorAsString());
+				}
+			}
+			else{
+				cs[message.size() - i] = (char)0;
+				if(send(s, cs, message.size() - i, 0) < 0){
+					throw socket_exception(std::string("Couldn't write to peer: ") + GetLastErrorAsString());
+				}
+			}
+		}
+	}
+	std::vector<char>receive(){
+		std::vector<char> stor;
+		while(true){
+			std::fill(buffer.begin(), buffer.end(), (char)0);
+			ssize_t val = recv(s, buffer.data(), buffersize + 1,0);
+			if(val == 0)throw socket_exception("Connection closed by peer");
+			if(val < 0){
+				throw socket_exception(GetLastErrorAsString());
+			}
+			stor.insert(stor.end(), buffer.begin(), buffer.begin() + std::min(val, (ssize_t)buffersize));
+			if(buffer.data()[buffersize] == (char)0){break;}
+		}
+		std::cout << std::endl;
+		return stor;
+	}
+	void close(){
+		closesocket(s);
+	}
+};
+class server_socket{
+private:
+	WSADATA wsaData;
+	int iResult;
+	SOCKET ListenSocket = INVALID_SOCKET;
+public:
+	server_socket(int port){
+		struct addrinfo *result = NULL;
+		struct addrinfo hints;
+		iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
+		if (iResult != 0) {
+			printf("WSAStartup failed with error: %d\n", iResult);
+		}
+		ZeroMemory(&hints, sizeof(hints));
+		hints.ai_family = AF_INET;
+		hints.ai_socktype = SOCK_STREAM;
+		hints.ai_protocol = IPPROTO_TCP;
+		hints.ai_flags = AI_PASSIVE;
+	
+		// Resolve the server address and port
+		iResult = getaddrinfo(NULL, std::to_string(port).c_str(), &hints, &result);
+		if ( iResult != 0 ) {
+			printf("getaddrinfo failed with error: %d\n", iResult);
+			WSACleanup();
+		}
+	
+		// Create a SOCKET for connecting to server
+		ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
+		if (ListenSocket == INVALID_SOCKET) {
+			printf("socket failed with error: %ld\n", WSAGetLastError());
+			freeaddrinfo(result);
+			WSACleanup();
+		}
+	
+		// Setup the TCP listening socket
+		iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
+		if (iResult == SOCKET_ERROR) {
+			printf("bind failed with error: %d\n", WSAGetLastError());
+			freeaddrinfo(result);
+			closesocket(ListenSocket);
+			WSACleanup();
+		}
+		freeaddrinfo(result);
+		iResult = listen(ListenSocket, SOMAXCONN);
+		if (iResult == SOCKET_ERROR) {
+			printf("listen failed with error: %d\n", WSAGetLastError());
+			closesocket(ListenSocket);
+			WSACleanup();
+		}
+	}
+	cppsocket accept_connection(){
+		SOCKET ClientSocket = accept(ListenSocket, NULL, NULL);
+		if (ClientSocket == INVALID_SOCKET) {
+			printf("accept failed with error: %d\n", WSAGetLastError());
+			closesocket(ListenSocket);
+			WSACleanup();
+		}
+		return cppsocket(wsaData, ClientSocket);
+	}
+	void close(){
+		closesocket(ListenSocket);
+	}
+};
+int main(int argc, char** argv){
+	server_socket ssock(80);
+	while(true){
+		cppsocket sock = ssock.accept_connection();
+		sock.write("ab");
+		std::vector<char> rec = sock.receive();
+		std::cout << rec << ", ";
+		std::cout << rec << std::endl;
+		sock.close();
+	}
+	ssock.close();
+	/*
+	//Send some data
+	std::string _message = std::string("Hallo");
+	memcpy(message, _message.c_str(), _message.length() + 1);
+	if( send(s , message , strlen(message) , 0) < 0){
+		puts("Send failed");
+		return 1;
+	}
+	puts("Data Send\n");
+	
+	//Receive a reply from the server
+	if((recv_size = recv(s , server_reply , 2000 , 0)) == SOCKET_ERROR){
+		puts("recv failed");
+	}
+	
+	puts("Reply received\n");
+	
+	//Add a NULL terminating character to make it a proper string before printing
+	server_reply[recv_size] = '\0';
+	puts(server_reply);
+	*/
+	return 0;
+}