向发送缓冲区写入udp数据,下面这例子是说明,一个udp数据包加上ip信息在网络层进行封装时,可能需要多次写入才能完成写进发送缓冲区,使用一个while
循环来实现。
@zhz: 写入发送缓冲区的数据是ip数据包
,并没有封装mac地址
,所以在将发送缓冲区中的数据发送出去后,加上mac地址
封装为以太网数据包
时,如果数据包太大,还得分成多帧
进行发送。
size_t UdpStream::write(const uint8_t* data, size_t length, uint8_t flag) {
size_t total_nsent = 0;
// if (flag) {
// peer_sockaddr_.sin_addr.s_addr = htonl(INADDR_BROADCAST);
// }
peer_sockaddr_.sin_addr.s_addr = peer_addr_;
peer_sockaddr_.sin_port = peer_broad_port_;
SDEBUG << "sendto addr: " << inet_ntoa(peer_sockaddr_.sin_addr)
<< ", port: " << ntohs(peer_sockaddr_.sin_port);
while (length > 0) {
// 把udp数据写入发送缓冲区
ssize_t nsent =
::sendto(sockfd_, data, length, 0, (struct sockaddr*)&peer_sockaddr_,
(socklen_t)sizeof(peer_sockaddr_));
if (nsent < 0) { // error
if (errno == EINTR) {
continue;
} else {
// error
if (errno == EPIPE || errno == ECONNRESET) {
status_ = Stream::Status::DISCONNECTED;
errno_ = errno;
} else if (errno != EAGAIN) {
status_ = Stream::Status::ERROR;
errno_ = errno;
}
return total_nsent;
}
}
total_nsent += nsent;
length -= nsent;
data += nsent;
}
return total_nsent;
}