added Socket::sendx() that accept a buffer vector and a destination address
This commit is contained in:
		| @ -444,7 +444,7 @@ public: | ||||
| 		return this->getValueAt(0); | ||||
| 	} | ||||
|  | ||||
| 	const T& getLast() const | ||||
| 	const T& getLast () const | ||||
| 	{ | ||||
| 		return this->getValueAt(this->getSize() - 1); | ||||
| 	} | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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)); | ||||
|  | ||||
| @ -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)); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user