Added ability to both send AND receive HTTP requests and responses.
This commit is contained in:
parent
7aced77a00
commit
fdee42e300
@ -4,5 +4,5 @@ project(frnetlib)
|
|||||||
include_directories(include)
|
include_directories(include)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -m64 -fPIC -pthread")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -m64 -fPIC -pthread")
|
||||||
|
|
||||||
set(SOURCE_FILES main.cpp src/TcpSocket.cpp include/TcpSocket.h src/TcpListener.cpp include/TcpListener.h src/Socket.cpp include/Socket.h src/Packet.cpp include/Packet.h include/NetworkEncoding.h src/SocketSelector.cpp include/SocketSelector.h src/HttpSocket.cpp include/HttpSocket.h include/HttpRequest.cpp include/HttpRequest.h)
|
set(SOURCE_FILES main.cpp src/TcpSocket.cpp include/TcpSocket.h src/TcpListener.cpp include/TcpListener.h src/Socket.cpp include/Socket.h src/Packet.cpp include/Packet.h include/NetworkEncoding.h src/SocketSelector.cpp include/SocketSelector.h src/HttpSocket.cpp include/HttpSocket.h src/HttpRequest.cpp include/HttpRequest.h src/HttpResponse.cpp include/HttpResponse.h)
|
||||||
add_executable(frnetlib ${SOURCE_FILES})
|
add_executable(frnetlib ${SOURCE_FILES})
|
||||||
@ -19,6 +19,7 @@ namespace fr
|
|||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
Get = 1,
|
Get = 1,
|
||||||
Post = 2,
|
Post = 2,
|
||||||
|
RequestTypeCount = 3,
|
||||||
};
|
};
|
||||||
enum RequestStatus
|
enum RequestStatus
|
||||||
{
|
{
|
||||||
@ -41,12 +42,26 @@ namespace fr
|
|||||||
*/
|
*/
|
||||||
void parse_request(const std::string &request_data);
|
void parse_request(const std::string &request_data);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Parses a browser response
|
||||||
|
*
|
||||||
|
* @param request_data The response data itself
|
||||||
|
*/
|
||||||
|
void parse_response(const std::string &response_data);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Gets the request type (post, get etc)
|
* Gets the request type (post, get etc)
|
||||||
*
|
*
|
||||||
* @return The request type
|
* @return The request type
|
||||||
*/
|
*/
|
||||||
RequestType type() const;
|
RequestType get_type() const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Sets the request type (post, get etc)
|
||||||
|
*
|
||||||
|
* @param type The type of request to set it to
|
||||||
|
*/
|
||||||
|
void set_type(RequestType type);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Access a header
|
* Access a header
|
||||||
@ -61,7 +76,14 @@ namespace fr
|
|||||||
*
|
*
|
||||||
* @return The HTTP request
|
* @return The HTTP request
|
||||||
*/
|
*/
|
||||||
std::string get_request() const;
|
std::string construct_request() const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Constructs a HTTP web response from the object.
|
||||||
|
*
|
||||||
|
* @return The HTTP response.
|
||||||
|
*/
|
||||||
|
std::string construct_response() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Sets the request body
|
* Sets the request body
|
||||||
@ -134,6 +156,20 @@ namespace fr
|
|||||||
*/
|
*/
|
||||||
RequestStatus get_status();
|
RequestStatus get_status();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Sets the request URI.
|
||||||
|
*
|
||||||
|
* @param str What to set the URI to.
|
||||||
|
*/
|
||||||
|
void set_uri(const std::string &str);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Gets the body of the HTTP request
|
||||||
|
*
|
||||||
|
* @return The request body
|
||||||
|
*/
|
||||||
|
const std::string &get_body() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*!
|
/*!
|
||||||
* Splits a string by new line. Ignores escaped \n's
|
* Splits a string by new line. Ignores escaped \n's
|
||||||
@ -142,6 +178,8 @@ namespace fr
|
|||||||
*/
|
*/
|
||||||
std::vector<std::string> split_string(const std::string &str);
|
std::vector<std::string> split_string(const std::string &str);
|
||||||
|
|
||||||
|
std::string request_type_to_string(RequestType type) const;
|
||||||
|
|
||||||
//Other request info
|
//Other request info
|
||||||
std::unordered_map<std::string, std::string> headers;
|
std::unordered_map<std::string, std::string> headers;
|
||||||
std::unordered_map<std::string, std::string> get_variables;
|
std::unordered_map<std::string, std::string> get_variables;
|
||||||
|
|||||||
15
include/HttpResponse.h
Normal file
15
include/HttpResponse.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Created by fred on 10/12/16.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef FRNETLIB_HTTPRESPONSE_H
|
||||||
|
#define FRNETLIB_HTTPRESPONSE_H
|
||||||
|
|
||||||
|
|
||||||
|
class HttpResponse
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //FRNETLIB_HTTPRESPONSE_H
|
||||||
@ -19,15 +19,31 @@ namespace fr
|
|||||||
* @param request The request to send
|
* @param request The request to send
|
||||||
* @return The status of the operation.
|
* @return The status of the operation.
|
||||||
*/
|
*/
|
||||||
Socket::Status receive(HttpRequest &request);
|
Socket::Status receive_request(HttpRequest &request);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Sends a HTTP response to the connected socket.
|
||||||
|
*
|
||||||
|
* @param request The response to send
|
||||||
|
* @return The status of the operation.
|
||||||
|
*/
|
||||||
|
Socket::Status receive_response(HttpRequest &response);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Sends a HTTP request to the connected socket.
|
* Sends a HTTP request to the connected socket.
|
||||||
*
|
*
|
||||||
* @param request Where to store the received request.
|
* @param request The HTTP request to send.
|
||||||
* @return The status of the operation.
|
* @return The status of the operation.
|
||||||
*/
|
*/
|
||||||
Socket::Status send(const HttpRequest &request);
|
Socket::Status send_request(const HttpRequest &request);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Sends a HTTP response to the connected socket.
|
||||||
|
*
|
||||||
|
* @param request The HTTP response to send.
|
||||||
|
* @return The status of the operation.
|
||||||
|
*/
|
||||||
|
Socket::Status send_response(const HttpRequest &request);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
51
main.cpp
51
main.cpp
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
void server()
|
void server()
|
||||||
{
|
{
|
||||||
|
//Bind to port
|
||||||
fr::TcpListener listener;
|
fr::TcpListener listener;
|
||||||
if(listener.listen("8081") != fr::Socket::Success)
|
if(listener.listen("8081") != fr::Socket::Success)
|
||||||
{
|
{
|
||||||
@ -17,15 +18,20 @@ void server()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Create a selector and a container for holding connected clients
|
||||||
fr::SocketSelector selector;
|
fr::SocketSelector selector;
|
||||||
std::vector<std::unique_ptr<fr::HttpSocket>> clients;
|
std::vector<std::unique_ptr<fr::HttpSocket>> clients;
|
||||||
|
|
||||||
|
//Add our connection listener to the selector
|
||||||
selector.add(listener);
|
selector.add(listener);
|
||||||
|
|
||||||
|
//Infinitely loop, waiting for connections or data
|
||||||
while(selector.wait())
|
while(selector.wait())
|
||||||
{
|
{
|
||||||
|
//If the listener is ready, that means we've got a new connection
|
||||||
if(selector.is_ready(listener))
|
if(selector.is_ready(listener))
|
||||||
{
|
{
|
||||||
|
//Try and add them to our client container
|
||||||
clients.emplace_back(new fr::HttpSocket());
|
clients.emplace_back(new fr::HttpSocket());
|
||||||
if(listener.accept(*clients.back()) != fr::Socket::Success)
|
if(listener.accept(*clients.back()) != fr::Socket::Success)
|
||||||
{
|
{
|
||||||
@ -33,23 +39,30 @@ void server()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Add them to the selector if connected successfully
|
||||||
selector.add(*clients.back());
|
selector.add(*clients.back());
|
||||||
std::cout << "Got new connection from: " << clients.back()->get_remote_address() << std::endl;
|
std::cout << "Got new connection from: " << clients.back()->get_remote_address() << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//Else it's one of the clients who's sent some data. Check each one
|
||||||
for(auto iter = clients.begin(); iter != clients.end();)
|
for(auto iter = clients.begin(); iter != clients.end();)
|
||||||
{
|
{
|
||||||
if(selector.is_ready(**iter))
|
if(selector.is_ready(**iter))
|
||||||
{
|
{
|
||||||
|
//This client has sent a HTTP request, so receive_request it
|
||||||
fr::HttpRequest request;
|
fr::HttpRequest request;
|
||||||
if((*iter)->receive(request) == fr::Socket::Success)
|
if((*iter)->receive_request(request) == fr::Socket::Success)
|
||||||
{
|
{
|
||||||
|
//Print to the console what we've been requested for
|
||||||
std::cout << "Requested: " << request.get_uri() << std::endl;
|
std::cout << "Requested: " << request.get_uri() << std::endl;
|
||||||
|
|
||||||
|
//Construct a response
|
||||||
request.clear();
|
request.clear();
|
||||||
request.set_body("<h1>Hello, World!</h1>");
|
request.set_body("<h1>Hello, World!</h1>");
|
||||||
|
|
||||||
(*iter)->send(request);
|
//Send the response, and close the connection
|
||||||
|
(*iter)->send_response(request);
|
||||||
(*iter)->close();
|
(*iter)->close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -70,19 +83,23 @@ void server()
|
|||||||
|
|
||||||
void client()
|
void client()
|
||||||
{
|
{
|
||||||
// fr::TcpSocket socket;
|
fr::HttpSocket socket;
|
||||||
// socket.connect("127.0.0.1", "8081");
|
if(socket.connect("127.0.0.1", "8081") != fr::Socket::Success)
|
||||||
//
|
{
|
||||||
// fr::TcpSocket socket2;
|
std::cout << "Failed to connect to web server!" << std::endl;
|
||||||
// socket2.connect("127.0.0.1", "8081");
|
return;
|
||||||
//
|
}
|
||||||
// fr::Packet packet;
|
|
||||||
// packet << "Hello, World! - From socket 1";
|
fr::HttpRequest request;
|
||||||
// socket.send(packet);
|
request.get("name") = "fred";
|
||||||
//
|
|
||||||
// packet.clear();
|
if(socket.send_request(request) != fr::Socket::Success)
|
||||||
// packet << "Hello, world! - From socket 2";
|
std::cout << "Failed to send HTTP request to server!" << std::endl;
|
||||||
// socket2.send(packet);
|
|
||||||
|
if(socket.receive_response(request) != fr::Socket::Success)
|
||||||
|
std::cout << "Failed to receive HTTP response from the server!" << std::endl;
|
||||||
|
|
||||||
|
std::cout << "Got page body: " << request.get_body() << std::endl;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -93,7 +110,9 @@ int main()
|
|||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
auto start = std::chrono::system_clock::now();
|
auto start = std::chrono::system_clock::now();
|
||||||
std::thread t2(&client);
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
|
||||||
|
client();
|
||||||
|
|
||||||
t1.join();
|
t1.join();
|
||||||
|
|
||||||
|
|||||||
@ -6,9 +6,11 @@
|
|||||||
|
|
||||||
namespace fr
|
namespace fr
|
||||||
{
|
{
|
||||||
|
const static std::string request_type_strings[HttpRequest::RequestType::RequestTypeCount] = {"UNKNOWN", "GET", "POST"};
|
||||||
|
|
||||||
HttpRequest::HttpRequest()
|
HttpRequest::HttpRequest()
|
||||||
: status(Ok)
|
|
||||||
{
|
{
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpRequest::parse_request(const std::string &request_data)
|
void HttpRequest::parse_request(const std::string &request_data)
|
||||||
@ -27,7 +29,7 @@ namespace fr
|
|||||||
if(lines.empty())
|
if(lines.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Extract request type
|
//Extract request get_type
|
||||||
if(lines[0].find("GET") != std::string::npos)
|
if(lines[0].find("GET") != std::string::npos)
|
||||||
request_type = RequestType::Get;
|
request_type = RequestType::Get;
|
||||||
else if(lines[0].find("POST") != std::string::npos)
|
else if(lines[0].find("POST") != std::string::npos)
|
||||||
@ -110,7 +112,58 @@ namespace fr
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpRequest::RequestType HttpRequest::type() const
|
void HttpRequest::parse_response(const std::string &response_data)
|
||||||
|
{
|
||||||
|
//Warning: Horrible string parsing code
|
||||||
|
std::cout << "Parsing response: " << std::endl << response_data << std::endl;
|
||||||
|
//Clear old headers/data
|
||||||
|
clear();
|
||||||
|
|
||||||
|
//Make sure there's actual request data to read
|
||||||
|
if(response_data.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Split by new lines
|
||||||
|
std::vector<std::string> lines = split_string(response_data);
|
||||||
|
if(lines.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Extract request get_type
|
||||||
|
if(lines[0].find("GET") != std::string::npos)
|
||||||
|
request_type = RequestType::Get;
|
||||||
|
else if(lines[0].find("POST") != std::string::npos)
|
||||||
|
request_type = RequestType::Post;
|
||||||
|
else
|
||||||
|
request_type = RequestType::Unknown;
|
||||||
|
|
||||||
|
//Extract headers
|
||||||
|
size_t a;
|
||||||
|
for(a = 1; a < lines.size(); a++)
|
||||||
|
{
|
||||||
|
//New line indicates headers have ended
|
||||||
|
if(lines[a].empty() || lines[a].size() <= 2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Find the colon separating the header name and header data
|
||||||
|
auto colon_iter = lines[a].find(":");
|
||||||
|
if(colon_iter == std::string::npos)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//Store the header
|
||||||
|
std::string header_name = lines[a].substr(0, colon_iter);
|
||||||
|
std::string header_content = lines[a].substr(colon_iter + 2, lines[a].size () - colon_iter - 3);
|
||||||
|
headers.emplace(header_name, header_content);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Store request body
|
||||||
|
for(; a < lines.size(); a++)
|
||||||
|
{
|
||||||
|
body += lines[a] + "\n";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpRequest::RequestType HttpRequest::get_type() const
|
||||||
{
|
{
|
||||||
return request_type;
|
return request_type;
|
||||||
}
|
}
|
||||||
@ -138,10 +191,10 @@ namespace fr
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HttpRequest::get_request() const
|
std::string HttpRequest::construct_request() const
|
||||||
{
|
{
|
||||||
//Add HTTP header
|
//Add HTTP header
|
||||||
std::string request = "HTTP/1.1 " + std::to_string(status) + " \r\n";
|
std::string request = request_type_to_string(request_type) + " " + uri + " HTTP/1.1\r\n";
|
||||||
|
|
||||||
//Add the headers to the request
|
//Add the headers to the request
|
||||||
for(const auto &header : headers)
|
for(const auto &header : headers)
|
||||||
@ -152,9 +205,7 @@ namespace fr
|
|||||||
|
|
||||||
//Add in required headers if they're missing
|
//Add in required headers if they're missing
|
||||||
if(headers.find("Connection") == headers.end())
|
if(headers.find("Connection") == headers.end())
|
||||||
request += "Connection: close\r\n";
|
request += "Connection: keep-alive\r\n";
|
||||||
if(headers.find("Content-type") == headers.end())
|
|
||||||
request += "Content-type: text/html\r\n";
|
|
||||||
|
|
||||||
//Add in space
|
//Add in space
|
||||||
request += "\r\n";
|
request += "\r\n";
|
||||||
@ -164,6 +215,32 @@ namespace fr
|
|||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string HttpRequest::construct_response() const
|
||||||
|
{
|
||||||
|
//Add HTTP header
|
||||||
|
std::string response = "HTTP/1.1 " + std::to_string(status) + " \r\n";
|
||||||
|
|
||||||
|
//Add the headers to the response
|
||||||
|
for(const auto &header : headers)
|
||||||
|
{
|
||||||
|
std::string data = header.first + ": " + header.second + "\r\n";
|
||||||
|
response += data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add in required headers if they're missing
|
||||||
|
if(headers.find("Connection") == headers.end())
|
||||||
|
response += "Connection: close\r\n";
|
||||||
|
if(headers.find("Content-type") == headers.end())
|
||||||
|
response += "Content-type: text/html\r\n";
|
||||||
|
|
||||||
|
//Add in space
|
||||||
|
response += "\r\n";
|
||||||
|
|
||||||
|
//Add in the body
|
||||||
|
response += body + "\r\n";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
void HttpRequest::set_body(const std::string &body_)
|
void HttpRequest::set_body(const std::string &body_)
|
||||||
{
|
{
|
||||||
body = body_;
|
body = body_;
|
||||||
@ -174,7 +251,9 @@ namespace fr
|
|||||||
headers.clear();
|
headers.clear();
|
||||||
body.clear();
|
body.clear();
|
||||||
get_variables.clear();
|
get_variables.clear();
|
||||||
|
uri = "/";
|
||||||
status = Ok;
|
status = Ok;
|
||||||
|
request_type = Get;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string &HttpRequest::get(const std::string &key)
|
std::string &HttpRequest::get(const std::string &key)
|
||||||
@ -211,4 +290,26 @@ namespace fr
|
|||||||
{
|
{
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HttpRequest::set_uri(const std::string &str)
|
||||||
|
{
|
||||||
|
uri = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string HttpRequest::request_type_to_string(RequestType type) const
|
||||||
|
{
|
||||||
|
if(type >= RequestType::RequestTypeCount)
|
||||||
|
return request_type_strings[0];
|
||||||
|
return request_type_strings[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
void HttpRequest::set_type(HttpRequest::RequestType type)
|
||||||
|
{
|
||||||
|
request_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &HttpRequest::get_body() const
|
||||||
|
{
|
||||||
|
return body;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
5
src/HttpResponse.cpp
Normal file
5
src/HttpResponse.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by fred on 10/12/16.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "HttpResponse.h"
|
||||||
@ -7,9 +7,9 @@
|
|||||||
namespace fr
|
namespace fr
|
||||||
{
|
{
|
||||||
|
|
||||||
Socket::Status HttpSocket::receive(HttpRequest &request)
|
Socket::Status HttpSocket::receive_request(HttpRequest &request)
|
||||||
{
|
{
|
||||||
//Create buffer to receive the request
|
//Create buffer to receive_request the request
|
||||||
std::string buffer(2048, '\0');
|
std::string buffer(2048, '\0');
|
||||||
|
|
||||||
//Receive the request
|
//Receive the request
|
||||||
@ -25,9 +25,33 @@ namespace fr
|
|||||||
return Socket::Success;
|
return Socket::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket::Status HttpSocket::send(const HttpRequest &request)
|
Socket::Status HttpSocket::receive_response(HttpRequest &response)
|
||||||
{
|
{
|
||||||
std::string data = request.get_request();
|
//Create buffer to receive_request the response
|
||||||
|
std::string buffer(2048, '\0');
|
||||||
|
|
||||||
|
//Receive the response
|
||||||
|
size_t received;
|
||||||
|
Socket::Status status = receive_raw(&buffer[0], buffer.size(), received);
|
||||||
|
if(status != Socket::Success)
|
||||||
|
return status;
|
||||||
|
buffer.resize(received);
|
||||||
|
|
||||||
|
//Parse it
|
||||||
|
response.parse_response(buffer);
|
||||||
|
|
||||||
|
return Socket::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket::Status HttpSocket::send_request(const HttpRequest &request)
|
||||||
|
{
|
||||||
|
std::string data = request.construct_request();
|
||||||
|
return send_raw(&data[0], data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket::Status HttpSocket::send_response(const HttpRequest &request)
|
||||||
|
{
|
||||||
|
std::string data = request.construct_response();
|
||||||
return send_raw(&data[0], data.size());
|
return send_raw(&data[0], data.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ namespace fr
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(::connect(socket_descriptor, c->ai_addr, c->ai_addrlen) == INVALID_SOCKET)
|
if(::connect(socket_descriptor, c->ai_addr, c->ai_addrlen) == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -187,12 +187,14 @@ namespace fr
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(c == nullptr)
|
||||||
|
return Socket::Status::Error;
|
||||||
|
|
||||||
//We're done with this now, cleanup
|
//We're done with this now, cleanup
|
||||||
freeaddrinfo(info);
|
freeaddrinfo(info);
|
||||||
|
|
||||||
if(c == nullptr)
|
|
||||||
return Socket::Status::Error;
|
|
||||||
is_connected = true;
|
is_connected = true;
|
||||||
|
|
||||||
return Socket::Status::Success;
|
return Socket::Status::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user