mawinkle 6 éve
szülő
commit
f424895def
5 módosított fájl, 451 hozzáadás és 3 törlés
  1. 49 0
      servertest.cpp
  2. 66 0
      socket_impl/socketio.hpp
  3. 130 0
      socket_impl/socketio_posix.cpp
  4. 202 0
      socket_impl/socketio_win32.cpp
  5. 4 3
      test.cpp

+ 49 - 0
servertest.cpp

@@ -0,0 +1,49 @@
+#include "socketio.hpp"
+#include <iostream>
+#include <exception>
+#include <random>
+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++){
+		out << o[i];
+	}
+	return out;
+}
+int main(){
+	std::uniform_int_distribution<unsigned char> dis(0,20);
+	std::mt19937_64 gen;
+	server_socket ssock(80);
+	while(true){
+		cppsocket sock = ssock.accept_connection();
+		try{
+			while(true){
+				std::vector<char> vec = sock.receive();
+				std::cout << "Received: " << vec << std::endl;
+				std::string resp(100, 'a');
+				for(unsigned int i = 0;i < resp.size();i++){
+					resp[i] = dis(gen) + 'a';
+				}
+				sock.write("Hallo " + resp);
+			}
+			sock.close();
+			std::cout << "Closed\n";
+		}
+		catch(const std::exception& e){
+			std::cout << e.what() << std::endl;
+		}
+		catch(...){
+			std::cout << "Unidentified exception" << std::endl;
+		}
+	}
+}

+ 66 - 0
socket_impl/socketio.hpp

@@ -0,0 +1,66 @@
+#ifndef SOCKETIO_HPP
+#define SOCKETIO_HPP
+#include <string>
+#include <cstring>
+#include <vector>
+#include <iostream>
+#include <exception>
+#include <cmath>
+#include <stdexcept>
+#ifndef _WIN32
+#include <sys/socket.h>
+#include <netinet/in.h>
+#else
+#define _WINSOCK_DEPRECATED_NO_WARNINGS
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#pragma comment(lib, "ws2_32.lib")
+#endif
+class cppsocket {
+private:
+#ifdef _WIN32
+	WSADATA wsa;
+	SOCKET s;
+#else
+	struct sockaddr_in serv_addr;
+	int sock;
+#endif
+	std::vector<char> buffer;
+public:
+	const static std::size_t buffersize = 1024;
+#ifdef _WIN32
+	cppsocket(WSADATA d, SOCKET _s);
+#else
+	cppsocket(sockaddr_in _serv_addr, int _sock);
+#endif
+	cppsocket();
+	cppsocket(const cppsocket& o) = delete;
+	cppsocket(cppsocket&& o);
+	cppsocket(const std::string& addr, unsigned int PORT);
+	void close();
+	int socket_id();
+	void write(const std::string& message);
+	void write(const std::vector<char>& message);
+	std::vector<char> receive();
+	cppsocket& operator=(cppsocket&& o);
+};
+
+class server_socket {
+private:
+#ifdef _WIN32
+	WSADATA wsaData;
+	int iResult;
+	SOCKET ListenSocket = INVALID_SOCKET;
+#else
+	int port_;
+	int server_fd;
+	struct sockaddr_in address;
+	socklen_t addrlen;
+#endif
+public:
+	int port();
+	server_socket(int _port);
+	cppsocket accept_connection();
+	void close();
+};
+#endif

+ 130 - 0
socket_impl/socketio_posix.cpp

@@ -0,0 +1,130 @@
+#include "socketio.hpp"
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <cinttypes>
+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 virtual char* what() const throw (){
+    	return msg.length() == 0 ? "Connection creation failure" : msg.c_str();
+    }
+};
+cppsocket::cppsocket(sockaddr_in _serv_addr,int _sock) : sock(_sock), serv_addr(_serv_addr){
+	buffer = std::vector<char>(buffersize + 1,0);
+}
+cppsocket::cppsocket(){buffer = std::vector<char>(buffersize + 1, 0);};
+cppsocket::cppsocket(const std::string& addr, unsigned int PORT){
+	struct sockaddr_in address;
+	sock = 0;
+	int valread;
+	buffer = std::vector<char>(buffersize + 1, 0);
+	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+		throw socket_exception("Socket creation error");
+	}
+	memset(&serv_addr, '0', sizeof(serv_addr));
+	serv_addr.sin_family = AF_INET;
+	serv_addr.sin_port = htons(PORT);
+	if(inet_pton(AF_INET, addr.c_str(), &serv_addr.sin_addr)<=0){
+		throw std::invalid_argument("Invalid address: " + addr);
+	}
+
+	if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
+		throw socket_exception("Could not reach server " + addr);
+	}
+}
+
+cppsocket::cppsocket(cppsocket&& o){
+	sock = o.sock;
+	o.sock = 0;
+	buffer = std::move(o.buffer);
+}
+int cppsocket::socket_id(){
+	return sock;
+}
+void cppsocket::close(){
+	shutdown(sock, 2);
+}
+void cppsocket::write(const std::string& message){
+	std::vector<char> msg(message.c_str(), message.c_str() + message.size());
+	write(msg);
+}
+void cppsocket::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(sock, cs, buffersize + 1, 0) < 0){
+				throw socket_exception(std::string("Couldn't write to peer: ") + strerror(errno));
+			}
+		}
+		else{
+			cs[message.size() - i] = (char)0;
+			if(send(sock, cs, message.size() - i, 0) < 0){
+				throw socket_exception(std::string("Couldn't write to peer: ") + strerror(errno));
+			}
+		}
+	}
+}
+std::vector<char> cppsocket::receive(){
+	std::vector<char> stor;
+	while(true){
+		std::fill(buffer.begin(), buffer.end(), (char)0);
+		ssize_t val = read(sock, buffer.data(), buffersize + 1);
+		if(val == 0)throw socket_exception("Connection closed by peer");
+		if(val < 0){
+			throw socket_exception(strerror(errno));
+		}
+		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;
+}
+server_socket::server_socket(int _port) : port_(_port){
+	int opt = 1;
+	addrlen = sizeof(address);
+	if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
+		throw socket_exception(std::string("server_socket creation failed: ") + strerror(errno));
+	}
+	if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
+		throw socket_exception(std::string("server_socket creation failed: ") + strerror(errno));
+	}
+	address.sin_family = AF_INET;
+	address.sin_addr.s_addr = INADDR_ANY;
+	address.sin_port = htons(port());
+	if(bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0){
+		throw socket_exception("Couldn't bind to port " + std::to_string(port()) + ", is it already in use?"); 
+	}
+	if (listen(server_fd, 16) < 0){
+		throw socket_exception("Error in listen() call, no clue why");
+	}
+}
+void server_socket::close(){
+	shutdown(server_fd, SHUT_RDWR);
+}
+cppsocket server_socket::accept_connection(){
+	int new_socket;
+	sockaddr client_addr;
+	if ((new_socket = accept(server_fd, (struct sockaddr *)&client_addr,(socklen_t*)&addrlen))<0){
+		throw socket_exception(std::string("Socket accept failed: ") + strerror(errno));
+	}
+	return cppsocket(*((sockaddr_in*)&client_addr), new_socket);
+}
+
+int server_socket::port(){return port_;}
+cppsocket& cppsocket::operator=(cppsocket&& o){
+	sock = o.sock;
+	o.sock = 0;
+	buffer = std::move(o.buffer);
+	return *this;
+}

+ 202 - 0
socket_impl/socketio_win32.cpp

@@ -0,0 +1,202 @@
+#include "socketio.hpp"
+#include <stdio.h>
+#include <cstdint>
+#include <cinttypes>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#pragma comment(lib, "ws2_32.lib")
+#include <string>
+#include <cstring>
+#include <vector>
+#include <iostream>
+
+#ifdef _MSC_VER
+#undef min
+#ifdef _WIN64
+using ssize_t = std::int64_t;
+#endif
+#ifndef _WIN64
+using ssize_t = std::int32_t;
+#endif
+template<typename T>
+const T& min(const T& a,const T& b){
+	return (b < a) ? b : a;
+}
+#else
+using std::min;
+#endif
+
+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 virtual char* what() const throw () {
+		//return "asdasdsa";
+		return msg.length() == 0 ? "Connection creation failure" : msg.c_str();
+	}
+};
+
+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;
+}
+
+cppsocket::cppsocket() {
+	buffer = std::vector<char>(buffersize + 1, 0);
+}
+cppsocket::cppsocket(cppsocket&& o) {
+	s = o.s;
+	o.s = INVALID_SOCKET;
+	buffer = std::move(o.buffer);
+}
+cppsocket::cppsocket(WSADATA d, SOCKET _s) {
+	s = _s;
+	wsa = d;
+	buffer = std::vector<char>(buffersize + 1, 0);
+}
+cppsocket::cppsocket(const std::string& addr, unsigned int PORT) {
+	struct sockaddr_in server;
+	buffer = std::vector<char>(buffersize + 1, 0);
+	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 cppsocket::write(const std::string& message) {
+	std::vector<char> msg(message.c_str(), message.c_str() + message.size());
+	write(msg);
+}
+void cppsocket::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> cppsocket::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() + min(val, (ssize_t)buffersize));
+		if (buffer.data()[buffersize] == (char)0) { break; }
+	}
+	std::cout << std::endl;
+	return stor;
+}
+void cppsocket::close() {
+	closesocket(s);
+}
+
+server_socket::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 server_socket::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 server_socket::close() {
+	closesocket(ListenSocket);
+}
+cppsocket& cppsocket::operator=(cppsocket&& o) {
+	s = o.s;
+	o.s = INVALID_SOCKET;
+	buffer = std::move(o.buffer);
+	return *this;
+}

+ 4 - 3
test.cpp

@@ -49,15 +49,16 @@ unsigned long long multTest(size_t s){
 	//std::cout << std::endl;
 	return std::accumulate(times.begin(), times.end(), 0ULL);
 }
+
 int main(){
 	BigInt a("4528437659827");
 	BigInt b(gen, 31);
 	BigInt res = a.modPow(b, secure_prime);
 	std::cout << res.toString() << std::endl;
-	return 0;
+	//return 0;
 	multTest(50);
-	multTest(100);
-	multTest(200);
+	//multTest(100);
+	//multTest(200);
 	std::cout << multTest(50 ) / 1000 / 1000 << " ms" << std::endl;
 	std::cout << multTest(100) / 1000 / 1000 << " ms" << std::endl;
 	std::cout << multTest(200) / 1000 / 1000 << " ms" << std::endl;