added Socket::sendx() that accept a buffer vector and a destination address

This commit is contained in:
hyung-hwan 2018-10-22 09:42:54 +00:00
parent 83f800799d
commit 1e08cd4f65
5 changed files with 99 additions and 13 deletions

View File

@ -444,7 +444,7 @@ public:
return this->getValueAt(0);
}
const T& getLast() const
const T& getLast () const
{
return this->getValueAt(this->getSize() - 1);
}

View File

@ -109,6 +109,7 @@ public:
int sendx (const void* buf, qse_size_t len, qse_size_t* total_sent = QSE_NULL) QSE_CPP_NOEXCEPT;
int sendx (const void* buf, qse_size_t len, const SocketAddress& dstaddr, qse_size_t* total_sent = QSE_NULL) QSE_CPP_NOEXCEPT;
int sendx (qse_ioptl_t* vec, int count, qse_size_t* total_sent = QSE_NULL) QSE_CPP_NOEXCEPT;
int sendx (qse_ioptl_t* vec, int count, const SocketAddress& dstaddr, qse_size_t* total_sent = QSE_NULL) QSE_CPP_NOEXCEPT;
qse_ssize_t receive (void* buf, qse_size_t len) QSE_CPP_NOEXCEPT;
qse_ssize_t receive (void* buf, qse_size_t len, SocketAddress& srcaddr) QSE_CPP_NOEXCEPT;

View File

@ -627,6 +627,101 @@ int Socket::sendx (qse_ioptl_t* iov, int count, qse_size_t* total_sent) QSE_CPP_
#endif
}
int Socket::sendx (qse_ioptl_t* iov, int count, const SocketAddress& dstaddr, qse_size_t* total_sent) QSE_CPP_NOEXCEPT
{
QSE_ASSERT (qse_is_sck_valid(this->handle));
#if defined(HAVE_SENDMSG)
int index = 0;
qse_size_t total = 0;
int backup_index = -1;
qse_ioptl_t backup;
struct msghdr msg;
QSE_MEMSET (&msg, 0, QSE_SIZEOF(msg));
msg.msg_name = (void*)dstaddr.getAddrPtr();
msg.msg_namelen = dstaddr.getAddrSize();
while (1)
{
ssize_t nwritten;
msg.msg_iov = (struct iovec*)&iov[index];
msg.msg_iovlen = count - index;
nwritten = ::sendmsg(this->handle, &msg, 0);
if (nwritten <= -1)
{
this->setErrorCode (syserr_to_errnum(errno));
if (backup_index >= 0) iov[backup_index] = backup;
if (total_sent) *total_sent = total;
return -1;
}
total += nwritten;
while (index < count && (qse_size_t)nwritten >= iov[index].len)
nwritten -= iov[index++].len;
if (index == count) break;
if (backup_index != index)
{
if (backup_index >= 0) iov[backup_index] = backup;
backup = iov[index];
backup_index = index;
}
iov[index].ptr = (void*)((qse_uint8_t*)iov[index].ptr + nwritten);
iov[index].len -= nwritten;
}
if (backup_index >= 0) iov[backup_index] = backup;
if (total_sent) *total_sent = total;
return 0;
#else
qse_ioptl_t* v, * ve;
qse_size_t total = 0, pos, rem;
ssize_t nwritten;
v = iov;
ve = v + count;
while (v < ve)
{
if (v->len <= 0)
{
v++;
continue;
}
pos = 0;
rem = v->len;
write_again:
nwritten = ::sendto(this->handle, (qse_uint8_t*)v->ptr + pos, rem, 0);
if (nwritten <= -1)
{
this->setErrorCode (syserr_to_errnum(errno));
if (total_sent) *total_sent = total;
return -1;
}
total += nwritten;
if ((qse_size_t)nwritten < rem)
{
pos += nwritten;
rem -= nwritten;
goto write_again;
}
v++;
}
if (total_sent) *total_sent = total;
return 0;
#endif
}
qse_ssize_t Socket::receive (void* buf, qse_size_t len) QSE_CPP_NOEXCEPT
{
QSE_ASSERT (qse_is_sck_valid(this->handle));

View File

@ -75,22 +75,12 @@
#endif
#if defined(AF_INET)
# define FAMILY(x) (((struct sockaddr_in*)(x))->sin_family)
#elif defined(AF_INET6)
# define FAMILY(x) (((struct sockaddr_in6*)(x))->sin6_family)
#elif defined(AF_UNIX)
# define FAMILY(x) (((struct sockaddr_un*)(x))->sun_family)
#else
# define FAMILY(x) (-1)
#endif
#define FAMILY(x) (((struct sockaddr*)(x))->sa_family)
#include <stdio.h>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
SocketAddress::SocketAddress () QSE_CPP_NOEXCEPT
{
QSE_MEMSET (&this->skad, 0, QSE_SIZEOF(this->skad));