// Implementation of the Socket class.
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <iostream>
#include "Socket.h"
const int MAXHOSTNAME = 200;
const int MAXCONNECTIONS = 5;
#define IS_SUCCEED(func) (func != -1)
Socket::Socket(int buffer_size) : m_sock(-1), m_buffer_size(buffer_size)
{
memset(&m_sockaddr, 0, sizeof(m_sockaddr));
m_buffer = new char[m_buffer_size + 1];
memset(m_buffer, 0, m_buffer_size + 1);
}
Socket::~Socket()
{
close();
if (m_buffer != NULL)
{
delete [] m_buffer;
m_buffer = NULL;
}
}
bool Socket::create()
{
m_sock = socket(AF_INET, SOCK_STREAM, 0);
if (is_invalid()) return false;
// TIME_WAIT - argh
int on = 1;
return IS_SUCCEED(setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (const void*)&on, sizeof(on)));
}
bool Socket::bind(const int port)
{
if (is_invalid()) return false;
m_sockaddr.sin_family = AF_INET;
m_sockaddr.sin_addr.s_addr = INADDR_ANY;
m_sockaddr.sin_port = htons(port);
return IS_SUCCEED(::bind(m_sock, (sockaddr*)&m_sockaddr, sizeof(m_sockaddr)));
}
bool Socket::listen() const
{
if (is_invalid()) return false;
return IS_SUCCEED(::listen(m_sock, MAXCONNECTIONS));
}
bool Socket::accept(Socket& new_socket) const
{
if (is_invalid()) return false;
socklen_t addr_length = sizeof(m_sockaddr);
new_socket.m_sock = ::accept(m_sock, (sockaddr*)&m_sockaddr, &addr_length);
return (new_socket.m_sock > 0);
}
bool Socket::connect(const std::string host, const int port)
{
if (is_invalid()) return false;
m_sockaddr.sin_family = AF_INET;
m_sockaddr.sin_port = htons(port);
inet_pton(AF_INET, host.c_str(), &m_sockaddr.sin_addr);
if (errno == EAFNOSUPPORT) return false;
return IS_SUCCEED(::connect(m_sock, (sockaddr*)&m_sockaddr, sizeof(m_sockaddr)));
}
bool Socket::send(const std::string s) const
{
return IS_SUCCEED(::send(m_sock, s.c_str(), s.size(), MSG_NOSIGNAL));
}
int Socket::recv(std::string& s) const
{
ssize_t bytes = ::recv(m_sock, m_buffer, m_buffer_size, 0);
if (bytes == -1)
{
std::cout << "bytes == -1 errno == " << errno << " in Socket::recv\n";
s = "";
}
else
{
m_buffer[bytes] = 0;
s = m_buffer;
}
return bytes;
}
void Socket::close()
{
if (m_sock != -1)
{
::close(m_sock);
m_sock = -1;
}
}
void Socket::set_non_blocking(const bool b)
{
if (is_invalid()) return;
int opts = fcntl(m_sock, F_GETFL);
if (opts < 0) return;
if (b)
opts = (opts | O_NONBLOCK );
else
opts = (opts & ~O_NONBLOCK );
fcntl(m_sock, F_SETFL, opts);
}
评论0