/* $Id$ | |
*/ | |
#ifndef __PJPP_SOCK_H__ | |
#define __PJPP_SOCK_H__ | |
#include <pj/sock.h> | |
#include <pj/string.h> | |
class Pj_Event_Handler; | |
// | |
// Base class for address. | |
// | |
class Pj_Addr | |
{ | |
}; | |
// | |
// Internet address. | |
// | |
class Pj_Inet_Addr : public pj_sockaddr_in, public Pj_Addr | |
{ | |
public: | |
// | |
// Get port number. | |
// | |
pj_uint16_t get_port_number() const | |
{ | |
return pj_sockaddr_in_get_port(this); | |
} | |
// | |
// Set port number. | |
// | |
void set_port_number(pj_uint16_t port) | |
{ | |
sin_family = PJ_AF_INET; | |
pj_sockaddr_in_set_port(this, port); | |
} | |
// | |
// Get IP address. | |
// | |
pj_uint32_t get_ip_address() const | |
{ | |
return pj_sockaddr_in_get_addr(this).s_addr; | |
} | |
// | |
// Get address string. | |
// | |
const char *get_address() const | |
{ | |
return pj_inet_ntoa(sin_addr); | |
} | |
// | |
// Set IP address. | |
// | |
void set_ip_address(pj_uint32_t addr) | |
{ | |
sin_family = PJ_AF_INET; | |
pj_sockaddr_in_set_addr(this, addr); | |
} | |
// | |
// Set address. | |
// | |
pj_status_t set_address(const pj_str_t *addr) | |
{ | |
return pj_sockaddr_in_set_str_addr(this, addr); | |
} | |
// | |
// Set address. | |
// | |
pj_status_t set_address(const char *addr) | |
{ | |
pj_str_t s; | |
return pj_sockaddr_in_set_str_addr(this, pj_cstr(&s, addr)); | |
} | |
// | |
// Compare for equality. | |
// | |
bool operator==(const Pj_Inet_Addr &rhs) const | |
{ | |
return sin_family == rhs.sin_family && | |
sin_addr.s_addr == rhs.sin_addr.s_addr && | |
sin_port == rhs.sin_port; | |
} | |
private: | |
// | |
// Dummy length used in pj_ioqueue_recvfrom() etc | |
// | |
friend class Pj_Event_Handler; | |
friend class Pj_Socket; | |
friend class Pj_Sock_Stream; | |
friend class Pj_Sock_Dgram; | |
int addrlen_; | |
}; | |
// | |
// Socket base class. | |
// | |
// Note: | |
// socket will not automatically be closed on destructor. | |
// | |
class Pj_Socket | |
{ | |
public: | |
// | |
// Default constructor. | |
// | |
Pj_Socket() | |
: sock_(PJ_INVALID_SOCKET) | |
{ | |
} | |
// | |
// Initialize from a socket handle. | |
// | |
explicit Pj_Socket(pj_sock_t sock) | |
: sock_(sock) | |
{ | |
} | |
// | |
// Copy constructor. | |
// | |
Pj_Socket(const Pj_Socket &rhs) | |
: sock_(rhs.sock_) | |
{ | |
} | |
// | |
// Destructor will not close the socket. | |
// You must call close() explicitly. | |
// | |
~Pj_Socket() | |
{ | |
} | |
// | |
// Set socket handle. | |
// | |
void set_handle(pj_sock_t sock) | |
{ | |
sock_ = sock; | |
} | |
// | |
// Get socket handle. | |
// | |
pj_sock_t get_handle() const | |
{ | |
return sock_; | |
} | |
// | |
// Get socket handle. | |
// | |
pj_sock_t& get_handle() | |
{ | |
return sock_; | |
} | |
// | |
// See if the socket is valid. | |
// | |
bool is_valid() const | |
{ | |
return sock_ != PJ_INVALID_SOCKET; | |
} | |
// | |
// Create the socket. | |
// | |
pj_status_t create(int af, int type, int proto) | |
{ | |
return pj_sock_socket(af, type, proto, &sock_); | |
} | |
// | |
// Bind socket. | |
// | |
pj_status_t bind(const Pj_Inet_Addr &addr) | |
{ | |
return pj_sock_bind(sock_, &addr, sizeof(Pj_Inet_Addr)); | |
} | |
// | |
// Close socket. | |
// | |
pj_status_t close() | |
{ | |
pj_sock_close(sock_); | |
} | |
// | |
// Get peer socket name. | |
// | |
pj_status_t getpeername(Pj_Inet_Addr *addr) | |
{ | |
return pj_sock_getpeername(sock_, addr, &addr->addrlen_); | |
} | |
// | |
// getsockname | |
// | |
pj_status_t getsockname(Pj_Inet_Addr *addr) | |
{ | |
return pj_sock_getsockname(sock_, addr, &addr->addrlen_); | |
} | |
// | |
// getsockopt. | |
// | |
pj_status_t getsockopt(int level, int optname, | |
void *optval, int *optlen) | |
{ | |
return pj_sock_getsockopt(sock_, level, optname, optval, optlen); | |
} | |
// | |
// setsockopt | |
// | |
pj_status_t setsockopt(int level, int optname, | |
const void *optval, int optlen) | |
{ | |
return pj_sock_setsockopt(sock_, level, optname, optval, optlen); | |
} | |
// | |
// receive data. | |
// | |
pj_ssize_t recv(void *buf, pj_size_t len, int flag = 0) | |
{ | |
pj_ssize_t bytes = len; | |
if (pj_sock_recv(sock_, buf, &bytes, flag) != PJ_SUCCESS) | |
return -1; | |
return bytes; | |
} | |
// | |
// send data. | |
// | |
pj_ssize_t send(const void *buf, pj_ssize_t len, int flag = 0) | |
{ | |
pj_ssize_t bytes = len; | |
if (pj_sock_send(sock_, buf, &bytes, flag) != PJ_SUCCESS) | |
return -1; | |
return bytes; | |
} | |
// | |
// connect. | |
// | |
pj_status_t connect(const Pj_Inet_Addr &addr) | |
{ | |
return pj_sock_connect(sock_, &addr, sizeof(Pj_Inet_Addr)); | |
} | |
// | |
// assignment. | |
// | |
Pj_Socket &operator=(const Pj_Socket &rhs) | |
{ | |
sock_ = rhs.sock_; | |
return *this; | |
} | |
protected: | |
friend class Pj_Event_Handler; | |
pj_sock_t sock_; | |
}; | |
#if PJ_HAS_TCP | |
// | |
// Stream socket. | |
// | |
class Pj_Sock_Stream : public Pj_Socket | |
{ | |
public: | |
// | |
// Default constructor. | |
// | |
Pj_Sock_Stream() | |
{ | |
} | |
// | |
// Initialize from a socket handle. | |
// | |
explicit Pj_Sock_Stream(pj_sock_t sock) | |
: Pj_Socket(sock) | |
{ | |
} | |
// | |
// Copy constructor. | |
// | |
Pj_Sock_Stream(const Pj_Sock_Stream &rhs) : Pj_Socket(rhs) | |
{ | |
} | |
// | |
// Assignment. | |
// | |
Pj_Sock_Stream &operator=(const Pj_Sock_Stream &rhs) | |
{ | |
sock_ = rhs.sock_; | |
return *this; | |
} | |
// | |
// listen() | |
// | |
pj_status_t listen(int backlog = 5) | |
{ | |
return pj_sock_listen(sock_, backlog); | |
} | |
// | |
// blocking accept() | |
// | |
Pj_Sock_Stream accept(Pj_Inet_Addr *remote_addr = NULL) | |
{ | |
pj_sock_t newsock; | |
int *addrlen = remote_addr ? &remote_addr->addrlen_ : NULL; | |
pj_status_t status; | |
status = pj_sock_accept(sock_, &newsock, remote_addr, addrlen); | |
if (status != PJ_SUCCESS) | |
return Pj_Sock_Stream(-1); | |
return Pj_Sock_Stream(newsock); | |
} | |
// | |
// shutdown() | |
// | |
pj_status_t shutdown(int how = PJ_SHUT_RDWR) | |
{ | |
return pj_sock_shutdown(sock_, how); | |
} | |
}; | |
#endif | |
// | |
// Datagram socket. | |
// | |
class Pj_Sock_Dgram : public Pj_Socket | |
{ | |
public: | |
// | |
// Default constructor. | |
// | |
Pj_Sock_Dgram() | |
{ | |
} | |
// | |
// Initialize from a socket handle. | |
// | |
explicit Pj_Sock_Dgram(pj_sock_t sock) | |
: Pj_Socket(sock) | |
{ | |
} | |
// | |
// Copy constructor. | |
// | |
Pj_Sock_Dgram(const Pj_Sock_Dgram &rhs) | |
: Pj_Socket(rhs) | |
{ | |
} | |
// | |
// Assignment. | |
// | |
Pj_Sock_Dgram &operator=(const Pj_Sock_Dgram &rhs) | |
{ | |
Pj_Socket::operator =(rhs); | |
return *this; | |
} | |
// | |
// recvfrom() | |
// | |
pj_ssize_t recvfrom( void *buf, pj_size_t len, int flag = 0, | |
Pj_Inet_Addr *fromaddr = NULL) | |
{ | |
pj_ssize_t bytes = len; | |
int *addrlen = fromaddr ? &fromaddr->addrlen_ : NULL; | |
if (pj_sock_recvfrom( sock_, buf, &bytes, flag, | |
fromaddr, addrlen) != PJ_SUCCESS) | |
{ | |
return -1; | |
} | |
return bytes; | |
} | |
// | |
// sendto() | |
// | |
pj_ssize_t sendto( const void *buf, pj_size_t len, int flag, | |
const Pj_Inet_Addr &addr) | |
{ | |
pj_ssize_t bytes = len; | |
if (pj_sock_sendto( sock_, buf, &bytes, flag, | |
&addr, sizeof(pj_sockaddr_in)) != PJ_SUCCESS) | |
{ | |
return -1; | |
} | |
return bytes; | |
} | |
}; | |
#endif /* __PJPP_SOCK_H__ */ |