Send/Receive works on TcpSocket now
This commit is contained in:
parent
533412d3d0
commit
d36a98b9b2
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.6)
|
|||||||
project(frnetlib)
|
project(frnetlib)
|
||||||
|
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
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)
|
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)
|
||||||
add_executable(frnetlib ${SOURCE_FILES})
|
add_executable(frnetlib ${SOURCE_FILES})
|
||||||
@ -46,6 +46,13 @@ inline double ntohd(double val)
|
|||||||
memcpy(&val, &ret, sizeof(val));
|
memcpy(&val, &ret, sizeof(val));
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
inline void *get_sin_addr(struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
if(sa->sa_family == AF_INET)
|
||||||
|
return &(((sockaddr_in*)sa)->sin_addr);
|
||||||
|
return &(((sockaddr_in6*)sa)->sin6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Windows and UNIX require some different headers.
|
//Windows and UNIX require some different headers.
|
||||||
//We also need some compatibility defines for cross platform support.
|
//We also need some compatibility defines for cross platform support.
|
||||||
|
|||||||
@ -7,17 +7,20 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
#include "NetworkEncoding.h"
|
#include "NetworkEncoding.h"
|
||||||
|
|
||||||
class Packet
|
namespace fr
|
||||||
{
|
{
|
||||||
public:
|
class Packet
|
||||||
|
{
|
||||||
|
public:
|
||||||
/*!
|
/*!
|
||||||
* Gets the data added to the packet
|
* Gets the data added to the packet
|
||||||
*
|
*
|
||||||
* @return A string containing all of the data added to the packet
|
* @return A string containing all of the data added to the packet
|
||||||
*/
|
*/
|
||||||
inline const std::string &construct_packet() const
|
inline const std::string &get_buffer() const
|
||||||
{
|
{
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
@ -131,9 +134,54 @@ public:
|
|||||||
var = ntohd(var);
|
var = ntohd(var);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
|
/*
|
||||||
|
* Adds a string variable to the packet
|
||||||
|
*/
|
||||||
|
inline Packet &operator<<(const std::string &var)
|
||||||
|
{
|
||||||
|
//Strings are prefixed with their length as a 32bit uint :)
|
||||||
|
*this << (uint32_t)var.length();
|
||||||
|
buffer += var;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removes a string variable from the packet
|
||||||
|
*/
|
||||||
|
inline Packet&operator>>(std::string &var)
|
||||||
|
{
|
||||||
|
uint32_t length;
|
||||||
|
*this >> length;
|
||||||
|
|
||||||
|
var = buffer.substr(0, length);
|
||||||
|
buffer.erase(0, length);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Sets the internal data buffer
|
||||||
|
*
|
||||||
|
* @param data What to set the packet to
|
||||||
|
*/
|
||||||
|
inline void set_buffer(std::string &&data)
|
||||||
|
{
|
||||||
|
buffer = std::move(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Clears all data from the packet
|
||||||
|
*/
|
||||||
|
inline void clear()
|
||||||
|
{
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
std::string buffer; //Packet data buffer
|
std::string buffer; //Packet data buffer
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //FRNETLIB_PACKET_H
|
#endif //FRNETLIB_PACKET_H
|
||||||
|
|||||||
@ -8,24 +8,33 @@
|
|||||||
|
|
||||||
#include "Packet.h"
|
#include "Packet.h"
|
||||||
|
|
||||||
class Socket
|
namespace fr
|
||||||
{
|
{
|
||||||
public:
|
class Socket
|
||||||
|
{
|
||||||
|
public:
|
||||||
enum Status
|
enum Status
|
||||||
{
|
{
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
Success = 1,
|
Success = 1,
|
||||||
ListenFailed = 2,
|
ListenFailed = 2,
|
||||||
BindFailed = 3
|
BindFailed = 3,
|
||||||
|
Disconnected = 4,
|
||||||
|
Error = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Socket()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Send a packet through the socket
|
* Send a packet through the socket
|
||||||
*
|
*
|
||||||
* @param packet The packet to send
|
* @param packet The packet to send
|
||||||
* @return True on success, false on failure.
|
* @return True on success, false on failure.
|
||||||
*/
|
*/
|
||||||
virtual bool send(const Packet &packet)=0;
|
virtual Status send(const Packet &packet)=0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Receive a packet through the socket
|
* Receive a packet through the socket
|
||||||
@ -33,13 +42,22 @@ public:
|
|||||||
* @param packet The packet to receive
|
* @param packet The packet to receive
|
||||||
* @return True on success, false on failure.
|
* @return True on success, false on failure.
|
||||||
*/
|
*/
|
||||||
virtual bool receive(Packet &packet)=0;
|
virtual Status receive(Packet &packet)=0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Close the connection.
|
* Close the connection.
|
||||||
*/
|
*/
|
||||||
virtual void close()=0;
|
virtual void close()=0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Connects the socket to an address.
|
||||||
|
*
|
||||||
|
* @param address The address of the socket to connect to
|
||||||
|
* @param port The port of the socket to connect to
|
||||||
|
* @return A Socket::Status indicating the status of the operation.
|
||||||
|
*/
|
||||||
|
virtual Socket::Status connect(const std::string &address, const std::string &port)=0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Sets the socket's printable remote address
|
* Sets the socket's printable remote address
|
||||||
*
|
*
|
||||||
@ -60,10 +78,11 @@ public:
|
|||||||
return remote_address;
|
return remote_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int socket_descriptor;
|
int socket_descriptor;
|
||||||
std::string remote_address;
|
std::string remote_address;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //FRNETLIB_SOCKET_H
|
#endif //FRNETLIB_SOCKET_H
|
||||||
|
|||||||
@ -16,8 +16,6 @@ namespace fr
|
|||||||
class TcpListener
|
class TcpListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TcpListener();
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Listens to the given port for connections
|
* Listens to the given port for connections
|
||||||
*
|
*
|
||||||
@ -35,8 +33,6 @@ public:
|
|||||||
Socket::Status accept(TcpSocket &client);
|
Socket::Status accept(TcpSocket &client);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void *get_sin_addr(struct sockaddr *sa);
|
|
||||||
addrinfo hints;
|
|
||||||
int socket_descriptor;
|
int socket_descriptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -5,21 +5,27 @@
|
|||||||
#ifndef FRNETLIB_TCPSOCKET_H
|
#ifndef FRNETLIB_TCPSOCKET_H
|
||||||
#define FRNETLIB_TCPSOCKET_H
|
#define FRNETLIB_TCPSOCKET_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include "Socket.h"
|
#include "Socket.h"
|
||||||
|
|
||||||
namespace fr
|
namespace fr
|
||||||
{
|
{
|
||||||
|
#define RECV_CHUNK_SIZE 1024 //How much data to try and recv at once
|
||||||
|
|
||||||
class TcpSocket : public Socket
|
class TcpSocket : public Socket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
TcpSocket() noexcept;
|
||||||
|
virtual ~TcpSocket() noexcept;
|
||||||
|
TcpSocket(TcpSocket &&) noexcept = default;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Send a packet through the socket
|
* Send a packet through the socket
|
||||||
*
|
*
|
||||||
* @param packet The packet to send
|
* @param packet The packet to send
|
||||||
* @return True on success, false on failure.
|
* @return True on success, false on failure.
|
||||||
*/
|
*/
|
||||||
virtual bool send(const Packet &packet);
|
virtual Status send(const Packet &packet);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Receive a packet through the socket
|
* Receive a packet through the socket
|
||||||
@ -27,13 +33,22 @@ public:
|
|||||||
* @param packet The packet to receive
|
* @param packet The packet to receive
|
||||||
* @return True on success, false on failure.
|
* @return True on success, false on failure.
|
||||||
*/
|
*/
|
||||||
virtual bool receive(Packet &packet);
|
virtual Status receive(Packet &packet);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Close the connection.
|
* Close the connection.
|
||||||
*/
|
*/
|
||||||
virtual void close();
|
virtual void close();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Connects the socket to an address.
|
||||||
|
*
|
||||||
|
* @param address The address of the socket to connect to
|
||||||
|
* @param port The port of the socket to connect to
|
||||||
|
* @return A Socket::Status indicating the status of the operation.
|
||||||
|
*/
|
||||||
|
virtual Socket::Status connect(const std::string &address, const std::string &port);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Sets the socket file descriptor.
|
* Sets the socket file descriptor.
|
||||||
*
|
*
|
||||||
@ -41,9 +56,29 @@ public:
|
|||||||
*/
|
*/
|
||||||
void set_descriptor(int descriptor);
|
void set_descriptor(int descriptor);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Checks to see if we're connected to a socket or not
|
||||||
|
*
|
||||||
|
* @return True if it's connected. False otherwise.
|
||||||
|
*/
|
||||||
|
inline bool connected() const
|
||||||
|
{
|
||||||
|
return is_connected;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ssize_t read_recv();
|
/*!
|
||||||
|
* Reads size bytes into dest from the socket.
|
||||||
|
*
|
||||||
|
* @param dest Where to read the data into
|
||||||
|
* @param size The number of bytes to read
|
||||||
|
* @return Operation status.
|
||||||
|
*/
|
||||||
|
Status read_recv(void *dest, size_t size);
|
||||||
|
|
||||||
std::string unprocessed_buffer;
|
std::string unprocessed_buffer;
|
||||||
|
std::unique_ptr<char[]> recv_buffer;
|
||||||
|
bool is_connected;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
48
main.cpp
48
main.cpp
@ -1,19 +1,47 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <Packet.h>
|
#include <Packet.h>
|
||||||
|
#include <TcpSocket.h>
|
||||||
|
#include <TcpListener.h>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
void server()
|
||||||
|
{
|
||||||
|
fr::TcpListener listener;
|
||||||
|
listener.listen("8081");
|
||||||
|
|
||||||
|
fr::TcpSocket socket;
|
||||||
|
listener.accept(socket);
|
||||||
|
|
||||||
|
while(socket.connected())
|
||||||
|
{
|
||||||
|
fr::Packet packet;
|
||||||
|
socket.receive(packet);
|
||||||
|
|
||||||
|
std::string message;
|
||||||
|
packet >> message;
|
||||||
|
std::cout << "Got: " << message << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void client()
|
||||||
|
{
|
||||||
|
fr::TcpSocket socket;
|
||||||
|
socket.connect("127.0.0.1", "8081");
|
||||||
|
|
||||||
|
fr::Packet packet;
|
||||||
|
packet << "Hello, World!";
|
||||||
|
socket.send(packet);
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Packet packet;
|
std::thread t1(&server);
|
||||||
packet << (uint16_t)15000 << (uint16_t)200 << (uint32_t)9299221 << (uint64_t)9223372036854775807 << (float)1.22 << (double)192.212;
|
|
||||||
std::cout << packet.construct_packet() << std::endl;
|
|
||||||
|
|
||||||
uint16_t result, result2;
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
uint32_t result3;
|
client();
|
||||||
uint64_t result4;
|
|
||||||
float result5;
|
|
||||||
double result6;
|
|
||||||
packet >> result >> result2 >> result3 >> result4 >> result5 >> result6;
|
|
||||||
|
|
||||||
std::cout << result << ", " << result2 << ", " << result3 << ", " << result4 << ", " << result5 << ", " << result6 << std::endl;
|
t1.join();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3,3 +3,8 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "Packet.h"
|
#include "Packet.h"
|
||||||
|
|
||||||
|
namespace fr
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@ -10,23 +10,23 @@ namespace fr
|
|||||||
const int yes = 1;
|
const int yes = 1;
|
||||||
const int no = 0;
|
const int no = 0;
|
||||||
|
|
||||||
TcpListener::TcpListener()
|
|
||||||
{
|
|
||||||
memset(&hints, 0, sizeof(addrinfo));
|
|
||||||
hints.ai_family = AF_UNSPEC; //IPv6 or IPv4. NOTE: Might want to make configurable.
|
|
||||||
hints.ai_socktype = SOCK_STREAM; //TCP
|
|
||||||
hints.ai_flags = AI_PASSIVE; //Have the IP filled in for us
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket::Status TcpListener::listen(const std::string &port)
|
Socket::Status TcpListener::listen(const std::string &port)
|
||||||
{
|
{
|
||||||
addrinfo *info;
|
addrinfo *info;
|
||||||
if(int status = getaddrinfo(NULL, port.c_str(), &hints, &info) != 0)
|
addrinfo hints;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(addrinfo));
|
||||||
|
|
||||||
|
hints.ai_family = AF_UNSPEC; //IPv6 or IPv4. NOTE: Might want to make configurable.
|
||||||
|
hints.ai_socktype = SOCK_STREAM; //TCP
|
||||||
|
hints.ai_flags = AI_PASSIVE; //Have the IP filled in for us
|
||||||
|
|
||||||
|
if(getaddrinfo(NULL, port.c_str(), &hints, &info) != 0)
|
||||||
{
|
{
|
||||||
return Socket::Status::Unknown;
|
return Socket::Status::Unknown;
|
||||||
}
|
}
|
||||||
//Try each of the results until we listen successfully
|
//Try each of the results until we listen successfully
|
||||||
addrinfo *c;
|
addrinfo *c = nullptr;
|
||||||
for(c = info; c != nullptr; c = c->ai_next)
|
for(c = info; c != nullptr; c = c->ai_next)
|
||||||
{
|
{
|
||||||
//Attempt to connect
|
//Attempt to connect
|
||||||
@ -90,11 +90,4 @@ namespace fr
|
|||||||
|
|
||||||
return Socket::Success;
|
return Socket::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *TcpListener::get_sin_addr(struct sockaddr *sa)
|
|
||||||
{
|
|
||||||
if(sa->sa_family == AF_INET)
|
|
||||||
return &(((sockaddr_in*)sa)->sin_addr);
|
|
||||||
return &(((sockaddr_in6*)sa)->sin6_addr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -2,49 +2,163 @@
|
|||||||
// Created by fred on 06/12/16.
|
// Created by fred on 06/12/16.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include "TcpSocket.h"
|
#include "TcpSocket.h"
|
||||||
|
|
||||||
namespace fr
|
namespace fr
|
||||||
{
|
{
|
||||||
|
|
||||||
bool TcpSocket::send(const Packet &packet)
|
TcpSocket::TcpSocket() noexcept
|
||||||
|
: recv_buffer(new char[RECV_CHUNK_SIZE]),
|
||||||
|
is_connected(false)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TcpSocket::~TcpSocket() noexcept
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket::Status TcpSocket::send(const Packet &packet)
|
||||||
{
|
{
|
||||||
size_t send_index = 0;
|
size_t send_index = 0;
|
||||||
size_t sent = 0;
|
size_t sent = 0;
|
||||||
|
|
||||||
while(sent < packet.construct_packet().size())
|
while(sent < packet.get_buffer().size())
|
||||||
{
|
{
|
||||||
ssize_t a = ::send(socket_descriptor, &packet.construct_packet()[send_index], packet.construct_packet().size(), 0);
|
ssize_t status = ::send(socket_descriptor, &packet.get_buffer()[send_index], packet.get_buffer().size(), 0);
|
||||||
if(a < 1)
|
if(status > 0)
|
||||||
return false;
|
{
|
||||||
sent += a;
|
sent += status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(status == -1)
|
||||||
|
{
|
||||||
|
return Socket::Status::Error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_connected = false;
|
||||||
|
return Socket::Status::Disconnected;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return Socket::Status::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TcpSocket::receive(Packet &packet)
|
Socket::Status TcpSocket::receive(Packet &packet)
|
||||||
{
|
{
|
||||||
std::string recv_buffer;
|
Socket::Status status;
|
||||||
|
|
||||||
//Read packet length
|
//Try to read packet length
|
||||||
uint32_t packet_length = 0;
|
uint32_t packet_length = 0;
|
||||||
|
status = read_recv(&packet_length, sizeof(packet_length));
|
||||||
|
if(status != Socket::Status::Success)
|
||||||
|
return status;
|
||||||
|
packet_length = ntohl(packet_length);
|
||||||
|
|
||||||
return false;
|
//Now we've got the length, read the rest of the data in
|
||||||
|
std::string data(packet_length, '\0');
|
||||||
|
read_recv(&data[0], packet_length);
|
||||||
|
|
||||||
|
//Set the packet to what we've read
|
||||||
|
packet.set_buffer(std::move(data));
|
||||||
|
|
||||||
|
return Socket::Status::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpSocket::close()
|
void TcpSocket::close()
|
||||||
|
{
|
||||||
|
if(!is_connected)
|
||||||
{
|
{
|
||||||
::close(socket_descriptor);
|
::close(socket_descriptor);
|
||||||
|
is_connected = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t TcpSocket::read_recv()
|
Socket::Status TcpSocket::read_recv(void *dest, size_t size)
|
||||||
{
|
{
|
||||||
return 0;
|
//See if there's enough data in the unprocessed buffer first
|
||||||
|
if(size < unprocessed_buffer.size())
|
||||||
|
{
|
||||||
|
memcpy(dest, &unprocessed_buffer[0], size);
|
||||||
|
unprocessed_buffer.erase(0, size);
|
||||||
|
return Socket::Status::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Else, keep calling recv until there's enough data in the buffer
|
||||||
|
while(unprocessed_buffer.size() < size)
|
||||||
|
{
|
||||||
|
//Read RECV_CHUNK_SIZE bytes into the recv buffer
|
||||||
|
ssize_t status = ::recv(socket_descriptor, recv_buffer.get(), RECV_CHUNK_SIZE, 0);
|
||||||
|
if(status > 0)
|
||||||
|
{
|
||||||
|
unprocessed_buffer += {recv_buffer.get(), (size_t)status};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(status == -1)
|
||||||
|
{
|
||||||
|
return Socket::Status::Error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_connected = false;
|
||||||
|
return Socket::Status::Disconnected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Socket::Status::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpSocket::set_descriptor(int descriptor)
|
void TcpSocket::set_descriptor(int descriptor)
|
||||||
{
|
{
|
||||||
socket_descriptor = descriptor;
|
socket_descriptor = descriptor;
|
||||||
|
is_connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Socket::Status TcpSocket::connect(const std::string &address, const std::string &port)
|
||||||
|
{
|
||||||
|
addrinfo *info;
|
||||||
|
addrinfo hints;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(addrinfo));
|
||||||
|
|
||||||
|
hints.ai_family = AF_UNSPEC; //IPv6 or IPv4
|
||||||
|
hints.ai_socktype = SOCK_STREAM; //TCP
|
||||||
|
hints.ai_flags = AI_PASSIVE; //Have the IP filled in for us
|
||||||
|
|
||||||
|
if(getaddrinfo(address.c_str(), port.c_str(), &hints, &info) != 0)
|
||||||
|
{
|
||||||
|
return Socket::Status::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
addrinfo *c;
|
||||||
|
for(c = info; c != nullptr; c = c->ai_next)
|
||||||
|
{
|
||||||
|
socket_descriptor = ::socket(c->ai_family, c->ai_socktype, c->ai_protocol);
|
||||||
|
if(socket_descriptor == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(::connect(socket_descriptor, c->ai_addr, c->ai_addrlen) == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//We're done with this now, cleanup
|
||||||
|
freeaddrinfo(info);
|
||||||
|
|
||||||
|
if(c == nullptr)
|
||||||
|
return Socket::Status::Error;
|
||||||
|
is_connected = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user