added Socket::sendx() that accept a buffer vector and a destination address
This commit is contained in:
		| @ -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)); | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user