slinky socks
This commit is contained in:
parent
c079f49be6
commit
bd35d65efc
6 changed files with 234 additions and 14 deletions
|
@ -15,21 +15,18 @@ int main(int argc, char **argv) {
|
|||
std::cout << i << std::endl;
|
||||
});*/
|
||||
|
||||
sosc::TcpClient client;
|
||||
sosc::TcpServer server;
|
||||
|
||||
server.Listen(1111);
|
||||
server.Accept(&client);
|
||||
/*sosc::TcpClient client;
|
||||
client.Open("127.0.0.1", 1111);
|
||||
|
||||
client.Send("test");
|
||||
std::string got;
|
||||
std::string got = "abc";
|
||||
|
||||
while(client.IsOpen()) {
|
||||
int length = client.Recv(&got);
|
||||
int length = client.Receive(&got);
|
||||
|
||||
if(length > 0)
|
||||
std::cout << got << std::endl;
|
||||
}
|
||||
}*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -36,13 +36,16 @@
|
|||
|
||||
#define SOSC_TCP_BUFLEN 2048
|
||||
|
||||
#define SOSC_TCP_APPEND 1
|
||||
#define SOSC_TCP_BLOCK 2
|
||||
|
||||
namespace sosc {
|
||||
class TcpClient {
|
||||
public:
|
||||
TcpClient();
|
||||
bool Open(std::string host, std::uint16_t port);
|
||||
|
||||
int Recv(std::string* str, bool append = false);
|
||||
int Receive(std::string* str, int flags = 0);
|
||||
int Send(const std::string& str);
|
||||
|
||||
bool IsDataReady();
|
||||
|
|
|
@ -10,14 +10,154 @@ sosc::TcpClient::TcpClient() {
|
|||
this->addr_len = -1;
|
||||
}
|
||||
|
||||
bool sosc::TcpClient::Init(std::string host, std::uint16_t port) {
|
||||
bool sosc::TcpClient::Open(std::string host, std::uint16_t port) {
|
||||
if(this->sock_open)
|
||||
return false;
|
||||
|
||||
struct addrinfo hints, *result, *ptr;
|
||||
struct addrinfo hints, *results, *ptr;
|
||||
bzero((char*)&hints, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
if(getaddrinfo(host.c_str(), TOSTR(port).c_str(), &hints, &results) != 0)
|
||||
return false;
|
||||
|
||||
for(ptr = results; ptr != NULL; ptr = ptr->ai_next) {
|
||||
this->sock = socket(ptr->ai_family,
|
||||
ptr->ai_socktype, ptr->ai_protocol);
|
||||
|
||||
if(this->sock < 0) {
|
||||
freeaddrinfo(results);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(connect(this->sock, ptr->ai_addr, (int)ptr->ai_addrlen) == 0)
|
||||
break;
|
||||
|
||||
close(this->sock);
|
||||
this->sock = -1;
|
||||
}
|
||||
|
||||
freeaddrinfo(results);
|
||||
if(this->sock < 0)
|
||||
return false;
|
||||
|
||||
this->sock_open = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void sosc::TcpClient::Open
|
||||
(SOSC_SOCK_T sock, SOSC_ADDR_T addr, int addr_len)
|
||||
{
|
||||
if(this->sock_open)
|
||||
return;
|
||||
|
||||
this->sock = sock;
|
||||
this->sock_open = true;
|
||||
|
||||
this->addr = addr;
|
||||
this->addr_len = addr_len;
|
||||
|
||||
char buffer[128];
|
||||
inet_ntop(addr.sin_family, (void*)&addr.sin_addr, buffer, 128);
|
||||
this->ip.Parse(buffer);
|
||||
}
|
||||
|
||||
int sosc::TcpClient::Receive(std::string* str, int flags) {
|
||||
if(!this->sock_open)
|
||||
return -1;
|
||||
|
||||
bool append = (flags & SOSC_TCP_APPEND) != 0,
|
||||
block = (flags & SOSC_TCP_BLOCK) != 0;
|
||||
|
||||
int total_length = 0;
|
||||
bool first_recv = true;
|
||||
while(block ? (first_recv ? true : this->IsDataReady())
|
||||
: this->IsDataReady())
|
||||
{
|
||||
int length = recv(this->sock, this->buffer, SOSC_TCP_BUFLEN, 0);
|
||||
if(length <= 0) {
|
||||
this->Close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(first_recv && !append)
|
||||
*str = std::string(this->buffer, length);
|
||||
else
|
||||
*str += std::string(this->buffer, length);
|
||||
|
||||
total_length += length;
|
||||
first_recv = false;
|
||||
}
|
||||
|
||||
return total_length;
|
||||
}
|
||||
|
||||
int sosc::TcpClient::Send(const std::string& str) {
|
||||
if(!this->sock_open)
|
||||
return -1;
|
||||
|
||||
std::string::size_type total_sent = 0;
|
||||
while(total_sent < str.length()) {
|
||||
int sent = total_sent == 0
|
||||
? send(this->sock, str.c_str(), str.length(), 0)
|
||||
: send(this->sock, str.substr(total_sent).c_str(),
|
||||
str.length() - total_sent, 0);
|
||||
|
||||
if(sent == -1) {
|
||||
this->Close();
|
||||
return -1;
|
||||
} else
|
||||
total_sent += sent;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool sosc::TcpClient::IsDataReady() {
|
||||
if(!this->sock_open)
|
||||
return false;
|
||||
|
||||
this->SetBlocking(false);
|
||||
int check = recv(this->sock, this->buffer, 1, MSG_PEEK),
|
||||
error = errno;
|
||||
this->SetBlocking(true);
|
||||
|
||||
if(check <= 0) {
|
||||
if(check != 0 && (error == EWOULDBLOCK || error == EAGAIN))
|
||||
return false;
|
||||
else {
|
||||
this->Close();
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
void sosc::TcpClient::SetBlocking(bool will_block) {
|
||||
if(!this->sock_open)
|
||||
return;
|
||||
|
||||
int flags = fcntl(this->sock, F_GETFL, 0);
|
||||
flags = will_block ? flags & ~O_NONBLOCK
|
||||
: flags | O_NONBLOCK;
|
||||
fcntl(this->sock, F_SETFL, flags);
|
||||
}
|
||||
|
||||
void sosc::TcpClient::Close() {
|
||||
if(!this->sock_open)
|
||||
return;
|
||||
|
||||
this->sock_open = false;
|
||||
shutdown(this->sock, SHUT_RDWR);
|
||||
close(this->sock);
|
||||
}
|
||||
|
||||
sosc::TcpClient::~TcpClient() {
|
||||
this->Close();
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* END TCPCLIENT CODE */
|
||||
/****************************/
|
||||
|
@ -25,7 +165,77 @@ bool sosc::TcpClient::Init(std::string host, std::uint16_t port) {
|
|||
/****************************/
|
||||
|
||||
sosc::TcpServer::TcpServer() {
|
||||
this->sock_open = false;
|
||||
}
|
||||
|
||||
bool sosc::TcpServer::Listen(uint16_t port) {
|
||||
if(this->sock_open)
|
||||
return false;
|
||||
|
||||
struct addrinfo hints, *result;
|
||||
bzero((char*)&hints, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
if(getaddrinfo(NULL, TOSTR(port).c_str(), &hints, &result) != 0)
|
||||
return false;
|
||||
|
||||
this->sock = socket(result->ai_family,
|
||||
result->ai_socktype, result->ai_protocol);
|
||||
|
||||
if(this->sock < 0) {
|
||||
freeaddrinfo(result);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(bind(this->sock, result->ai_addr, (int)result->ai_addrlen) < 0) {
|
||||
freeaddrinfo(result);
|
||||
close(this->sock);
|
||||
return false;
|
||||
}
|
||||
|
||||
freeaddrinfo(result);
|
||||
if(listen(this->sock, SOMAXCONN) < 0) {
|
||||
close(this->sock);
|
||||
return false;
|
||||
}
|
||||
|
||||
this->sock_open = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
int sosc::TcpServer::Accept(TcpClient* client) {
|
||||
if(!this->sock_open)
|
||||
return -1;
|
||||
|
||||
SOSC_SOCK_T sock;
|
||||
SOSC_ADDR_T addr;
|
||||
unsigned int addr_len = sizeof(addr);
|
||||
|
||||
sock = accept(this->sock, (struct sockaddr*)&addr, &addr_len);
|
||||
if(sock < 0) {
|
||||
this->Close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
client->Close();
|
||||
client->Open(sock, addr, addr_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sosc::TcpServer::Close() {
|
||||
if(!this->sock_open)
|
||||
return;
|
||||
|
||||
this->sock_open = false;
|
||||
shutdown(this->sock, SHUT_RDWR);
|
||||
close(this->sock);
|
||||
}
|
||||
|
||||
sosc::TcpServer::~TcpServer() {
|
||||
this->Close();
|
||||
}
|
||||
|
||||
/****************************/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "tcpsock.hpp"
|
||||
#ifdef _WIN32
|
||||
|
||||
void init_wsa() {
|
||||
static void init_wsa() {
|
||||
static bool is_inited = false;
|
||||
if(is_inited) return;
|
||||
|
||||
|
@ -80,7 +80,7 @@ void sosc::TcpClient::Open
|
|||
this->ip.Parse(buffer);
|
||||
}
|
||||
|
||||
int sosc::TcpClient::Recv(std::string* str, bool append) {
|
||||
int sosc::TcpClient::Receive(std::string* str, bool append) {
|
||||
if(!this->sock_open)
|
||||
return -1;
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
|
||||
#include "websock.hpp"
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
#ifndef SOSC_WEBSOCK_H
|
||||
#define SOSC_WEBSOCK_H
|
||||
|
||||
#include "tcpsock.hpp"
|
||||
|
||||
namespace sosc {
|
||||
class WebSocketClient {
|
||||
|
||||
};
|
||||
|
||||
class WebSocketServer {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue