improve send semantics, documentation
This commit is contained in:
@@ -378,11 +378,12 @@ int TcpSocket::Send (const uint8_t* buf, uint32_t size)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << buf << size);
|
||||
if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
|
||||
{ // Ok to buffer some data to send
|
||||
{
|
||||
if (size > GetTxAvailable ())
|
||||
{
|
||||
size = std::min(size, GetTxAvailable() ); //only buffer what can fit
|
||||
m_wouldBlock = true;
|
||||
m_errno = ERROR_MSGSIZE;
|
||||
return -1;
|
||||
}
|
||||
if (!m_pendingData)
|
||||
{
|
||||
|
||||
@@ -37,6 +37,8 @@ NS_LOG_COMPONENT_DEFINE ("UdpSocket");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
static const uint32_t MAX_IPV4_UDP_DATAGRAM_SIZE = 65507;
|
||||
|
||||
TypeId
|
||||
UdpSocket::GetTypeId (void)
|
||||
{
|
||||
@@ -302,6 +304,12 @@ UdpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (p->GetSize () > GetTxAvailable () )
|
||||
{
|
||||
m_errno = ERROR_MSGSIZE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t localIfIndex;
|
||||
Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
|
||||
|
||||
@@ -344,12 +352,15 @@ UdpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// XXX maximum message size for UDP broadcast is limited by MTU
|
||||
// size of underlying link; we are not checking that now.
|
||||
uint32_t
|
||||
UdpSocket::GetTxAvailable (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
// No finite send buffer is modelled
|
||||
return std::numeric_limits<uint32_t>::max ();
|
||||
// No finite send buffer is modelled, but we must respect
|
||||
// the maximum size of an IP datagram (65535 bytes - headers).
|
||||
return MAX_IPV4_UDP_DATAGRAM_SIZE;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -240,11 +240,12 @@ PacketSocket::Send (Ptr<Packet> p)
|
||||
return SendTo (p, m_destAddr);
|
||||
}
|
||||
|
||||
// XXX must limit it to interface MTU
|
||||
uint32_t
|
||||
PacketSocket::GetTxAvailable (void) const
|
||||
{
|
||||
// No finite send buffer is modelled
|
||||
return 0xffffffff;
|
||||
// Use 65536 for now
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -277,6 +278,11 @@ PacketSocket::SendTo(Ptr<Packet> p, const Address &address)
|
||||
m_errno = ERROR_AFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
if (p->GetSize () > GetTxAvailable ())
|
||||
{
|
||||
m_errno = ERROR_MSGSIZE;
|
||||
return -1;
|
||||
}
|
||||
ad = PacketSocketAddress::ConvertFrom (address);
|
||||
|
||||
bool error = false;
|
||||
|
||||
@@ -257,15 +257,50 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Send data (or dummy data) to the remote host
|
||||
* \param p packet to send
|
||||
* \returns -1 in case of error or the number of bytes copied in the
|
||||
* internal buffer and accepted for transmission.
|
||||
*
|
||||
* This function matches closely in semantics to the send() function
|
||||
* call in the standard C library (libc):
|
||||
* ssize_t send (int s, const void *msg, size_t len, int flags);
|
||||
* except that the function call is asynchronous.
|
||||
*
|
||||
* In a typical blocking sockets model, this call would block upon
|
||||
* lack of space to hold the message to be sent. In ns-3 at this
|
||||
* API, the call returns immediately in such a case, but the callback
|
||||
* registered with SetSendCallback() is invoked when the socket
|
||||
* has space (when it conceptually unblocks); this is an asynchronous
|
||||
* I/O model for send().
|
||||
*
|
||||
* This variant of Send() uses class ns3::Packet to encapsulate
|
||||
* data, rather than providing a raw pointer and length field.
|
||||
* This allows an ns-3 application to attach tags if desired (such
|
||||
* as a flow ID) and may allow the simulator to avoid some data
|
||||
* copies. Despite the appearance of sending Packets on a stream
|
||||
* socket, just think of it as a fancy byte buffer with streaming
|
||||
* semantics.
|
||||
*
|
||||
* If either the message buffer within the Packet is too long to pass
|
||||
* atomically through the underlying protocol (for datagram sockets),
|
||||
* or the message buffer cannot entirely fit in the transmit buffer
|
||||
* (for stream sockets), -1 is returned and SocketErrno is set
|
||||
* to ERROR_MSGSIZE. If the packet does not fit, the caller can
|
||||
* split the Packet (based on information obtained from
|
||||
* GetTxAvailable) and reattempt to send the data.
|
||||
*
|
||||
* \param p ns3::Packet to send
|
||||
* \returns the number of bytes accepted for transmission if no error
|
||||
* occurs, and -1 otherwise.
|
||||
*/
|
||||
virtual int Send (Ptr<Packet> p) = 0;
|
||||
|
||||
/**
|
||||
* returns the number of bytes which can be sent in a single call
|
||||
* \brief Returns the number of bytes which can be sent in a single call
|
||||
* to Send.
|
||||
*
|
||||
* For datagram sockets, this returns the number of bytes that
|
||||
* can be passed atomically through the underlying protocol.
|
||||
*
|
||||
* For stream sockets, this returns the available space in bytes
|
||||
* left in the transmit buffer.
|
||||
*/
|
||||
virtual uint32_t GetTxAvailable (void) const = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user