parent
							
								
									89a1b75bd2
								
							
						
					
					
						commit
						d9659374c7
					
				
				 25 changed files with 627 additions and 0 deletions
			
			
		@ -0,0 +1,51 @@ | 
				
			|||||||
 | 
					project "bakanet" | 
				
			||||||
 | 
					    location "./bakanet" | 
				
			||||||
 | 
						kind "StaticLib" | 
				
			||||||
 | 
					    language "C++" | 
				
			||||||
 | 
					    cppdialect "C++17" | 
				
			||||||
 | 
					    systemversion "latest" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    targetdir("%{wks.location}/bin/" .. outputdir .. "/%{prj.name}") | 
				
			||||||
 | 
					    objdir("%{wks.location}/bin-int/" .. outputdir .. "/%{prj.name}") | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    includedirs  | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        "%{IncludeDirs.bakanet}" | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    files  | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        "%{prj.location}/src/bakanet/**.h", | 
				
			||||||
 | 
					        "%{prj.location}/src/bakanet/**.cpp", | 
				
			||||||
 | 
					        "%{prj.location}/src/bakanet.h", | 
				
			||||||
 | 
					        "%{prj.location}/src/baknetpch.h", | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    filter "system:windows" | 
				
			||||||
 | 
					        defines | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            "BK_PLAFORM_WINDOWS" | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        files | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            "%{prj.location}/src/plaform/windows/**.h", | 
				
			||||||
 | 
					            "%{prj.location}/src/plaform/windows/**.cpp", | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        links | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            "WS2_32.lib" | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					     | 
				
			||||||
 | 
					    filter "system:linux" | 
				
			||||||
 | 
					        defines | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            "BK_PLAFORM_LINUX" | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        files | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            "%{prj.location}/src/plaform/linux/**.h", | 
				
			||||||
 | 
					            "%{prj.location}/src/plaform/linux/**.cpp", | 
				
			||||||
 | 
					        } | 
				
			||||||
@ -0,0 +1,6 @@ | 
				
			|||||||
 | 
					#pragma once  | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <bakanet/ip_address.h> | 
				
			||||||
 | 
					#include <bakanet/packet.h> | 
				
			||||||
 | 
					#include <bakanet/socket.h> | 
				
			||||||
 | 
					#include <bakanet/dns_lookup.h> | 
				
			||||||
@ -0,0 +1,42 @@ | 
				
			|||||||
 | 
					#include "http_parser.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HttpRequest http_parser(std::string req) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    std::string url = "", method = "", body = ""; | 
				
			||||||
 | 
					    std::unordered_map<std::string, std::string> params; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto lines = string_split(req, "\n"); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto first_line = string_split(lines->at(0), " "); | 
				
			||||||
 | 
					    method = string_to_upper(first_line->at(0)); | 
				
			||||||
 | 
					    url = first_line->at(1); | 
				
			||||||
 | 
					    body = lines->at(lines->size() - 1); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lines->erase(lines->begin()); | 
				
			||||||
 | 
					    lines->pop_back(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (auto line : *lines) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto param = string_split(line, ":", 1); | 
				
			||||||
 | 
					        if (param->size() == 2) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            params.insert({ param->at(0), string_trim(param->at(1))}); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    return HttpRequest { | 
				
			||||||
 | 
					        http_resolve_methode(method), | 
				
			||||||
 | 
					        url, | 
				
			||||||
 | 
					        params, | 
				
			||||||
 | 
					        body | 
				
			||||||
 | 
					    }; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HttpMethod http_resolve_methode(std::string method) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (method.compare("GET")) return HttpMethod::GET; | 
				
			||||||
 | 
					    else if (method.compare("POST")) return HttpMethod::POST; | 
				
			||||||
 | 
					    else if (method.compare("PUT")) return HttpMethod::PUT; | 
				
			||||||
 | 
					    else if (method.compare("DELETE")) return HttpMethod::DELETE; | 
				
			||||||
 | 
					    else return HttpMethod::NONE; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,26 @@ | 
				
			|||||||
 | 
					#include <unordered_map> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <commun.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "http_tools.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum class HttpMethod | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    NONE = 0, | 
				
			||||||
 | 
					    GET = 1, | 
				
			||||||
 | 
					    POST = 2, | 
				
			||||||
 | 
					    PUT = 3, | 
				
			||||||
 | 
					    DELETE = 4, | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HttpRequest 
 | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    public: | 
				
			||||||
 | 
					        HttpMethod method; | 
				
			||||||
 | 
					        std::string url; | 
				
			||||||
 | 
					        std::unordered_map<std::string, std::string> params; | 
				
			||||||
 | 
					        std::string body; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HttpRequest http_parser(std::string req); | 
				
			||||||
 | 
					HttpMethod http_resolve_methode(std::string method); | 
				
			||||||
@ -0,0 +1,48 @@ | 
				
			|||||||
 | 
					#include "http_server.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void http_server() 
 | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    IpAddress ip("127.0.0.1"); | 
				
			||||||
 | 
					    Socket sock(ip, PORT, IpProtocol::TCP); | 
				
			||||||
 | 
					    bool running = sock.init() && sock.start(5); | 
				
			||||||
 | 
					    char input = 'N'; | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    do | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        Connection conn = sock.ack(); | 
				
			||||||
 | 
					        if (conn >= 0) 
 | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            std::string http_request(http_handler(sock, conn)); | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (http_request == "") continue; | 
				
			||||||
 | 
					            HttpRequest req = http_parser(http_request); | 
				
			||||||
 | 
					            log("Http request"); | 
				
			||||||
 | 
					            log("Method " << (int)req.method) | 
				
			||||||
 | 
					            log("URL " << req.url) | 
				
			||||||
 | 
					            log("Body " << req.body) | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        log("Close?") | 
				
			||||||
 | 
					        input(input); | 
				
			||||||
 | 
					    } while (input != 'y'); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string http_handler(Socket& sock, Connection conn) 
 | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    Packet req; | 
				
			||||||
 | 
					    bool reading = true; | 
				
			||||||
 | 
					    while(reading) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        std::vector<char> raw_data; | 
				
			||||||
 | 
					        raw_data = sock.recv(conn, 4); | 
				
			||||||
 | 
					        reading = req.append_data(raw_data); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    close(conn); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int req_size = req.size(); | 
				
			||||||
 | 
					    std::unique_ptr<char[]> req_test = req.pull<char>(req_size); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (req_size) return std::string(req_test.release(), req_size); | 
				
			||||||
 | 
					    return ""; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,7 @@ | 
				
			|||||||
 | 
					#include <commun.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "http_parser.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace Bk::Net; | 
				
			||||||
 | 
					void http_server(); | 
				
			||||||
 | 
					std::string http_handler(Socket& sock, Connection conn); | 
				
			||||||
@ -0,0 +1,34 @@ | 
				
			|||||||
 | 
					#include "http_tools.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string string_to_upper(std::string& str) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    for (int i = 0; i < str.length(); i++) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        str[i] = std::toupper(str[i]); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    return str; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::unique_ptr<std::vector<std::string>> string_split(std::string s, std::string delimiter, int cpt) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    std::unique_ptr<std::vector<std::string>> splits(new std::vector<std::string>(0)); | 
				
			||||||
 | 
					    size_t pos = 0; | 
				
			||||||
 | 
					    while (((pos = s.find(delimiter)) != std::string::npos) && cpt-- != 0) { | 
				
			||||||
 | 
					        splits->push_back(s.substr(0, pos)); | 
				
			||||||
 | 
					        s.erase(0, pos + delimiter.length()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    splits->push_back(s); | 
				
			||||||
 | 
					    return splits; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string string_trim(const std::string& str, const std::string& whitespace) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    const auto strBegin = str.find_first_not_of(whitespace); | 
				
			||||||
 | 
					    if (strBegin == std::string::npos) | 
				
			||||||
 | 
					        return ""; // no content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto strEnd = str.find_last_not_of(whitespace); | 
				
			||||||
 | 
					    const auto strRange = strEnd - strBegin + 1; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return str.substr(strBegin, strRange); | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,7 @@ | 
				
			|||||||
 | 
					#include <cstring> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <commun.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string string_to_upper(std::string& str); | 
				
			||||||
 | 
					std::unique_ptr<std::vector<std::string>> string_split(std::string s, std::string delimiter, int cpt = -1); | 
				
			||||||
 | 
					std::string string_trim(const std::string& str, const std::string& whitespace = " "); | 
				
			||||||
@ -0,0 +1,9 @@ | 
				
			|||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <bakanetpch.h> | 
				
			||||||
 | 
					#include "ip_version.h" | 
				
			||||||
 | 
					#include "ip_address.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bk::Net { | 
				
			||||||
 | 
						std::vector<std::string> dns_lookup(const std::string& host_name, IpVersion ipv); | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,15 @@ | 
				
			|||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <bakanetpch.h> | 
				
			||||||
 | 
					#include "ip_version.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bk::Net { | 
				
			||||||
 | 
						class IpAddress 
 | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
						public: | 
				
			||||||
 | 
							IpAddress(std::string ip, IpVersion ipv = IpVersion::IPv4);		
 | 
				
			||||||
 | 
							void* get_data(); | 
				
			||||||
 | 
							std::string str; | 
				
			||||||
 | 
							IpVersion version; | 
				
			||||||
 | 
						}; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,11 @@ | 
				
			|||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <bakanetpch.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bk::Net { | 
				
			||||||
 | 
						enum class IpProtocol 
 | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							TCP = SOCK_STREAM, | 
				
			||||||
 | 
							UCP = SOCK_DGRAM, | 
				
			||||||
 | 
						}; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,10 @@ | 
				
			|||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bk::Net { | 
				
			||||||
 | 
						enum class IpVersion | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							UnSpec = AF_UNSPEC, | 
				
			||||||
 | 
							IPv4 = AF_INET, | 
				
			||||||
 | 
							IPv6 = AF_INET6, | 
				
			||||||
 | 
						}; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,57 @@ | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bk::Net { | 
				
			||||||
 | 
						class Packet 
 | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
						public: | 
				
			||||||
 | 
							Packet() = default; | 
				
			||||||
 | 
							Packet(std::vector<char> data) | 
				
			||||||
 | 
							: payload(data) {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int size() { return payload.size(); } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							template <typename T> | 
				
			||||||
 | 
							void push(const T& data) | 
				
			||||||
 | 
							{ | 
				
			||||||
 | 
								static_assert(std::is_standard_layout<T>::value, "Data is too complex to be pushed into vector"); | 
				
			||||||
 | 
								size_t i = payload.size(); | 
				
			||||||
 | 
								payload.resize(i + sizeof(T)); | 
				
			||||||
 | 
								std::memcpy(payload.data() + i, &data, sizeof(T)); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							template <typename T> | 
				
			||||||
 | 
							void push(const T* data, int size) | 
				
			||||||
 | 
							{ | 
				
			||||||
 | 
								for(int i = 0; i < size; i++) push<T>(data[i]);	
 | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							template <typename T> | 
				
			||||||
 | 
							T pull() | 
				
			||||||
 | 
							{ | 
				
			||||||
 | 
								static_assert(std::is_standard_layout<T>::value, "Data is too complex to be pulled from vector"); | 
				
			||||||
 | 
								T data; | 
				
			||||||
 | 
								size_t i = payload.size() - sizeof(T); | 
				
			||||||
 | 
								std::memcpy(&data, payload.data() + i, sizeof(T)); | 
				
			||||||
 | 
								payload.resize(i); | 
				
			||||||
 | 
								return data; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							template <typename T> | 
				
			||||||
 | 
							std::unique_ptr<T[]> pull(int size) | 
				
			||||||
 | 
							{ | 
				
			||||||
 | 
								std::unique_ptr<T[]> data(new T[size]); | 
				
			||||||
 | 
								for(int i = size - 1; i >= 0; i--) data[i] = pull<T>(); | 
				
			||||||
 | 
								return data; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bool append_data(std::vector<char> data) | 
				
			||||||
 | 
							{ | 
				
			||||||
 | 
								if (!data.size()) return false; | 
				
			||||||
 | 
								size_t i = payload.size(); | 
				
			||||||
 | 
								payload.resize(i + data.size()); | 
				
			||||||
 | 
								std::memcpy(payload.data() + i, data.data(), sizeof(char) * data.size()); | 
				
			||||||
 | 
								return true; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
							std::vector<char> payload; | 
				
			||||||
 | 
						}; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,27 @@ | 
				
			|||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <bakanetpch.h> | 
				
			||||||
 | 
					#include "ip_address.h" | 
				
			||||||
 | 
					#include "ip_protocol.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bk::Net { | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						using Connection = int; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						class Socket 
 | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
						public: | 
				
			||||||
 | 
							virtual ~Socket() { } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							virtual bool init() = 0; | 
				
			||||||
 | 
							virtual bool start(int cpt_conn) = 0; | 
				
			||||||
 | 
							virtual Connection ack() = 0; | 
				
			||||||
 | 
							virtual bool conn() = 0; | 
				
			||||||
 | 
							virtual void emit(std::vector<char> packet) = 0; | 
				
			||||||
 | 
							virtual void emit(Connection socket, std::vector<char> packet) = 0; | 
				
			||||||
 | 
							virtual std::vector<char> obtain(int size) = 0; | 
				
			||||||
 | 
							virtual std::vector<char> obtain(Connection socket, int size) = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							static std::unique_ptr<Socket> Create(IpAddress ip, int port, IpProtocol proto); | 
				
			||||||
 | 
						}; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,26 @@ | 
				
			|||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstring> | 
				
			||||||
 | 
					#include <vector> | 
				
			||||||
 | 
					#include <string> | 
				
			||||||
 | 
					#include <exception> | 
				
			||||||
 | 
					#include <memory> | 
				
			||||||
 | 
					#include <cstdint> | 
				
			||||||
 | 
					#include <cctype> | 
				
			||||||
 | 
					#include <string> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef BK_PLAFORM_WINDOWS | 
				
			||||||
 | 
					    #include <Ws2tcpip.h> | 
				
			||||||
 | 
					    #include <WinSock2.h> | 
				
			||||||
 | 
					    #include <tchar.h> | 
				
			||||||
 | 
					    #pragma comment(lib,"WS2_32.lib") | 
				
			||||||
 | 
					#elif BK_PLAFORM_LINUX | 
				
			||||||
 | 
					    #include <netinet/in.h> | 
				
			||||||
 | 
					    #include <stdlib.h> | 
				
			||||||
 | 
					    #include <sys/socket.h> | 
				
			||||||
 | 
					    #include <unistd.h> | 
				
			||||||
 | 
					    #include <netdb.h> | 
				
			||||||
 | 
					    #include <arpa/inet.h> | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    #error "Plaform not supported" | 
				
			||||||
 | 
					#endif | 
				
			||||||
@ -0,0 +1,43 @@ | 
				
			|||||||
 | 
					#include "dns_lookup.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bk::Net { | 
				
			||||||
 | 
						std::vector<std::string> dns_lookup(const std::string &host_name, IpVersion ipv) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
						    std::vector<std::string> output; | 
				
			||||||
 | 
						 
 | 
				
			||||||
 | 
						    struct addrinfo hints, *res, *p; | 
				
			||||||
 | 
						    int status, ai_family; | 
				
			||||||
 | 
						    char ip_address[INET6_ADDRSTRLEN]; | 
				
			||||||
 | 
						 
 | 
				
			||||||
 | 
						    ai_family = (int)ipv; | 
				
			||||||
 | 
						    memset(&hints, 0, sizeof hints); | 
				
			||||||
 | 
						    hints.ai_family = ai_family; 
 | 
				
			||||||
 | 
						    hints.ai_socktype = SOCK_STREAM; | 
				
			||||||
 | 
						 
 | 
				
			||||||
 | 
						    if ((status = getaddrinfo(host_name.c_str(), NULL, &hints, &res)) != 0) 
 | 
				
			||||||
 | 
							{ | 
				
			||||||
 | 
						        output.push_back(""); | 
				
			||||||
 | 
						        return output; | 
				
			||||||
 | 
						    } | 
				
			||||||
 | 
						 
 | 
				
			||||||
 | 
						    for(p = res;p != NULL; p = p->ai_next) 
 | 
				
			||||||
 | 
							{ | 
				
			||||||
 | 
						        void *addr; | 
				
			||||||
 | 
						        if (p->ai_family == AF_INET) 
 | 
				
			||||||
 | 
								{ | 
				
			||||||
 | 
						            struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; | 
				
			||||||
 | 
						            addr = &(ipv4->sin_addr); | 
				
			||||||
 | 
						        } else 
 | 
				
			||||||
 | 
								{ | 
				
			||||||
 | 
						            struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr; | 
				
			||||||
 | 
						            addr = &(ipv6->sin6_addr); | 
				
			||||||
 | 
						        } | 
				
			||||||
 | 
						        inet_ntop(p->ai_family, addr, ip_address, sizeof ip_address); | 
				
			||||||
 | 
						        output.push_back(ip_address); | 
				
			||||||
 | 
						    } | 
				
			||||||
 | 
						 
 | 
				
			||||||
 | 
						    freeaddrinfo(res); // free the linked list
 | 
				
			||||||
 | 
						 
 | 
				
			||||||
 | 
						    return output; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,14 @@ | 
				
			|||||||
 | 
					#include <bakanet/sock_layer/ip_address.h> | 
				
			||||||
 | 
					#include <string.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bk::Net { | 
				
			||||||
 | 
					    IpAddress::IpAddress(std::string ip, IpVersion ipv) | 
				
			||||||
 | 
					    : str(ip), version(ipv) { } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void* IpAddress::get_data() 
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        struct in_addr addr; | 
				
			||||||
 | 
					        if (inet_pton(AF_INET, str.c_str(), &addr) <= 0) perror("Bad IP"); | 
				
			||||||
 | 
					        return (void*)addr; 
 | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,93 @@ | 
				
			|||||||
 | 
					#include "socket.h" | 
				
			||||||
 | 
					#include <iostream> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bk::Net { | 
				
			||||||
 | 
						LinuxSocket::LinuxSocket(IpAddress ip, int port, IpProtocol proto) | 
				
			||||||
 | 
						: ip_addr(ip), ip_proto(proto) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							//LinuxSocket creation step
 | 
				
			||||||
 | 
							if ((socket_id = socket((int)ip_addr.version, (int)ip_proto, 0)) < 0) 
 | 
				
			||||||
 | 
							{ | 
				
			||||||
 | 
						        perror("socket failed"); | 
				
			||||||
 | 
						        exit(EXIT_FAILURE); | 
				
			||||||
 | 
						    } | 
				
			||||||
 | 
						    addr.sin_addr = (struct in_addr)ip_addr.get_data(); | 
				
			||||||
 | 
							addr.sin_family = (int)ip_addr.version; | 
				
			||||||
 | 
					    	addr.sin_port = htons(port); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						LinuxSocket::~LinuxSocket() | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							close(socket_id); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool LinuxSocket::init() | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
						    //Binding step
 | 
				
			||||||
 | 
							int status; | 
				
			||||||
 | 
						    if ((status = bind(socket_id, (struct sockaddr*)&addr, sizeof(addr)) < 0)) 
 | 
				
			||||||
 | 
						    { | 
				
			||||||
 | 
								perror("bind failed"); | 
				
			||||||
 | 
						      	return false; | 
				
			||||||
 | 
						    } | 
				
			||||||
 | 
						    return true; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool LinuxSocket::start(int cpt_conn) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
						    //Listening step
 | 
				
			||||||
 | 
						    if (listen(socket_id, cpt_conn) < 0) 
 | 
				
			||||||
 | 
						    { | 
				
			||||||
 | 
						    	return false; | 
				
			||||||
 | 
						    } | 
				
			||||||
 | 
						    return true; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Connection LinuxSocket::ack() | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							socklen_t addrlen = sizeof(addr); | 
				
			||||||
 | 
							return accept(socket_id, (struct sockaddr*)&addr, &addrlen); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool LinuxSocket::conn() | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							if (connect(socket_id, (struct sockaddr*)&addr, sizeof(addr)) < 0) 
 | 
				
			||||||
 | 
							{ | 
				
			||||||
 | 
						        return false; | 
				
			||||||
 | 
					    	} | 
				
			||||||
 | 
					    	return true; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void LinuxSocket::emit(std::vector<char> packet) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							write(socket_id, packet.data(), packet.size()); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void LinuxSocket::emit(Connection conn, std::vector<char> packet) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							write(conn, packet.data(), packet.size()); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::vector<char> LinuxSocket::obtain(int size) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							std::vector<char> buffer; | 
				
			||||||
 | 
							buffer.resize(size); | 
				
			||||||
 | 
							int status = read(socket_id, buffer.data(), buffer.size() - 1); | 
				
			||||||
 | 
							return status > 0 ? buffer : std::vector<char>(); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::vector<char> LinuxSocket::obtain(Connection conn, int size) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							std::vector<char> buffer; | 
				
			||||||
 | 
							buffer.resize(size); | 
				
			||||||
 | 
							int read_size = read(conn, buffer.data(), buffer.size() - 1); | 
				
			||||||
 | 
							buffer.resize(read_size); | 
				
			||||||
 | 
							return buffer; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::unique_ptr<Socket> Socket::Create(IpAddress ip, int port, IpProtocol proto) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							return std::unique_ptr(new LinuxSocket(ip, port, proto)); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,27 @@ | 
				
			|||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <bakanet/tcp_ip/socket.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bk::Net { | 
				
			||||||
 | 
						class LinuxSocket : public Socket | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
					        public: | 
				
			||||||
 | 
					            LinuxSocket(IpAddress ip, int port, IpProtocol proto); | 
				
			||||||
 | 
					            virtual ~LinuxSocket(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            bool init() override; | 
				
			||||||
 | 
					            bool start(int cpt_conn) override; | 
				
			||||||
 | 
					            Connection ack() override; | 
				
			||||||
 | 
					            bool conn() override; | 
				
			||||||
 | 
					            void emit(std::vector<char> packet) override; | 
				
			||||||
 | 
					            void emit(Connection socket, std::vector<char> packet) override; | 
				
			||||||
 | 
					            std::vector<char> obtain(int size) override; | 
				
			||||||
 | 
					            std::vector<char> obtain(Connection socket, int size) override; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private: | 
				
			||||||
 | 
					            Connection socket_id; | 
				
			||||||
 | 
					            struct sockaddr_in addr; | 
				
			||||||
 | 
					            IpAddress ip_addr; | 
				
			||||||
 | 
					            IpProtocol ip_proto; | 
				
			||||||
 | 
						}; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,71 @@ | 
				
			|||||||
 | 
					workspace "socket_unix" | 
				
			||||||
 | 
					   	architecture "x64" | 
				
			||||||
 | 
					    configurations { "Debug", "Release" } | 
				
			||||||
 | 
					    startproject "server" | 
				
			||||||
 | 
					    flags | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							"MultiProcessorCompile" | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					outputdir = "%{cfg.system}-%{cfg.architecture}-%{cfg.buildcfg}" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IncludeDirs = {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IncludeDirs["bakanet"] = "%{wks.location}/bakanet/src/" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					project "server" | 
				
			||||||
 | 
					    location "./sandbox/server" | 
				
			||||||
 | 
					    kind "ConsoleApp" | 
				
			||||||
 | 
					    language "C++" | 
				
			||||||
 | 
					    cppdialect "C++17" | 
				
			||||||
 | 
					    systemversion "latest" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    targetdir("%{wks.location}/bin/" .. outputdir .. "/%{prj.name}") | 
				
			||||||
 | 
					    objdir("%{wks.location}/bin-int/" .. outputdir .. "/%{prj.name}") | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    includedirs  | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        "%{IncludeDirs.bakanet}", | 
				
			||||||
 | 
					        "./sandbox/" | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    files  | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        "%{prj.location}/**.h", | 
				
			||||||
 | 
					        "%{prj.location}/**.cpp", | 
				
			||||||
 | 
					        "./sandbox/commun.h" | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    links | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        "bakanet" | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					project "client" | 
				
			||||||
 | 
					    location "./sandbox/client" | 
				
			||||||
 | 
					    kind "ConsoleApp" | 
				
			||||||
 | 
					    language "C++" | 
				
			||||||
 | 
					    cppdialect "C++17" | 
				
			||||||
 | 
					    systemversion "latest" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    targetdir("%{wks.location}/bin/" .. outputdir .. "/%{prj.name}") | 
				
			||||||
 | 
					    objdir("%{wks.location}/bin-int/" .. outputdir .. "/%{prj.name}") | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    includedirs  | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        "%{IncludeDirs.bakanet}" | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    files  | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        "%{prj.location}/**.h", | 
				
			||||||
 | 
					        "%{prj.location}/**.cpp", | 
				
			||||||
 | 
					        "./sandbox/commun.h" | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					     | 
				
			||||||
 | 
					    links | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        "bakanet" | 
				
			||||||
 | 
					    } | 
				
			||||||
					Loading…
					
					
				
		Reference in New Issue