added Socket::sendx() that accept a buffer vector and a destination address
This commit is contained in:
parent
83f800799d
commit
1e08cd4f65
@ -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, 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 (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, 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) QSE_CPP_NOEXCEPT;
|
||||||
qse_ssize_t receive (void* buf, qse_size_t len, SocketAddress& srcaddr) QSE_CPP_NOEXCEPT;
|
qse_ssize_t receive (void* buf, qse_size_t len, SocketAddress& srcaddr) QSE_CPP_NOEXCEPT;
|
||||||
|
@ -627,6 +627,101 @@ int Socket::sendx (qse_ioptl_t* iov, int count, qse_size_t* total_sent) QSE_CPP_
|
|||||||
#endif
|
#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_ssize_t Socket::receive (void* buf, qse_size_t len) QSE_CPP_NOEXCEPT
|
||||||
{
|
{
|
||||||
QSE_ASSERT (qse_is_sck_valid(this->handle));
|
QSE_ASSERT (qse_is_sck_valid(this->handle));
|
||||||
|
@ -75,22 +75,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(AF_INET)
|
#define FAMILY(x) (((struct sockaddr*)(x))->sa_family)
|
||||||
# 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
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
QSE_BEGIN_NAMESPACE(QSE)
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
SocketAddress::SocketAddress () QSE_CPP_NOEXCEPT
|
SocketAddress::SocketAddress () QSE_CPP_NOEXCEPT
|
||||||
{
|
{
|
||||||
QSE_MEMSET (&this->skad, 0, QSE_SIZEOF(this->skad));
|
QSE_MEMSET (&this->skad, 0, QSE_SIZEOF(this->skad));
|
||||||
|
Loading…
Reference in New Issue
Block a user