From 1e08cd4f65a109b04bd19283993a8c2d8884aea4 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 22 Oct 2018 09:42:54 +0000 Subject: [PATCH] added Socket::sendx() that accept a buffer vector and a destination address --- qse/include/qse/cmn/Array.hpp | 2 +- qse/include/qse/dhcp/dhcp6msg.h | 2 +- qse/include/qse/si/Socket.hpp | 1 + qse/lib/si/Socket.cpp | 95 +++++++++++++++++++++++++++++++++ qse/lib/si/SocketAddress.cpp | 12 +---- 5 files changed, 99 insertions(+), 13 deletions(-) diff --git a/qse/include/qse/cmn/Array.hpp b/qse/include/qse/cmn/Array.hpp index 174d67ed..a01f22a9 100644 --- a/qse/include/qse/cmn/Array.hpp +++ b/qse/include/qse/cmn/Array.hpp @@ -444,7 +444,7 @@ public: return this->getValueAt(0); } - const T& getLast() const + const T& getLast () const { return this->getValueAt(this->getSize() - 1); } diff --git a/qse/include/qse/dhcp/dhcp6msg.h b/qse/include/qse/dhcp/dhcp6msg.h index 9282481b..2c03a561 100644 --- a/qse/include/qse/dhcp/dhcp6msg.h +++ b/qse/include/qse/dhcp/dhcp6msg.h @@ -78,7 +78,7 @@ extern "C" { QSE_EXPORT qse_dhcp6_opt_hdr_t* qse_dhcp6_find_option ( const qse_dhcp6_pktinf_t* pkt, - int code + int code ); #ifdef __cplusplus diff --git a/qse/include/qse/si/Socket.hpp b/qse/include/qse/si/Socket.hpp index fa1466b2..a322f97d 100644 --- a/qse/include/qse/si/Socket.hpp +++ b/qse/include/qse/si/Socket.hpp @@ -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; diff --git a/qse/lib/si/Socket.cpp b/qse/lib/si/Socket.cpp index 9b8a41cb..4a978361 100644 --- a/qse/lib/si/Socket.cpp +++ b/qse/lib/si/Socket.cpp @@ -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)); diff --git a/qse/lib/si/SocketAddress.cpp b/qse/lib/si/SocketAddress.cpp index e862b24d..67936f38 100644 --- a/qse/lib/si/SocketAddress.cpp +++ b/qse/lib/si/SocketAddress.cpp @@ -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 ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// - SocketAddress::SocketAddress () QSE_CPP_NOEXCEPT { QSE_MEMSET (&this->skad, 0, QSE_SIZEOF(this->skad));