Sending Large Packets but Not Receiving them

145 views
Skip to first unread message

Synnove Svendsen

unread,
Sep 17, 2024, 8:37:50 PM9/17/24
to ns-3-users
Hello, I am trying to send roughly 490 KBs to and from clients and a server but I am struggling to manage this. I am using UDP and found the receive buffer size is "131072" and I tried to enlarge this using the SetRcvBufSize attribute for the socket. I also tried manually setting the default config and tried switching to TCP to set the SndBufSize as well. I realize that I could fragment my packets and was able to do this, but ideally, I need to be able to send these larger packets without fragmentation (or compression). 

I currently have a setup with UDP and the OLSR protocol and can send up to a packet size of roughly 6000. After this point, the flow monitor shows packets getting lost, or in the case of 10,000, the flow monitor does not even pick up the transmission. This makes some sense given the constraints; however, I would like to know if these can be expanded. I found another discussion where someone was sending 108,000 bytes and they had some success with increasing the MCS, but this does not work for my case, nor does increasing the simulation time (for the TCP) method. 

For some other information, I am trying to simulate a FL scenario using an ad-hoc network in ns3 version 3.47.

(My apologies if I missed something in the docs. If this is the case, could you please link below?)

Tommaso Pecorella

unread,
Sep 18, 2024, 3:07:39 AM9/18/24
to ns-3-users
Sorry, but I'm very confused by your description. In particular I can't understand if you're referring to a packet (a single packet) or a stream of data (divided into multiple packets).

TCP doesn't care (mostly) about the amount of data you pass through a single Send call, because it will do its own packetization. Hence, if you can't receive the data using TCP you have an issue on the network level, like routing, radio range, channel errors, and so on.
However, TCP does recover the channel errors, so unless your channel is really horrible it should work.

UDP will try to use a single packet for each Send, and the limit (hard one, you can't do anything about it) is about 65.000 bytes. The resulting packet MIGHT be fragmented by IP tho.
On the other hand, UDP doesn't try to recover channel errors, so if you loose a bit, you loose the whole packet, and for large packets this is very likely.

Last point is about Path MTU. IPv4 doesn't have a [reliable] way to discover the Path MTU, so if you cross the boundary between networks with different MTU, your packets can be lost.

Synnove Svendsen

unread,
Sep 18, 2024, 9:06:32 PM9/18/24
to ns-3-users
Tom, thank you for responding to my question. My apologies for the poor description. I wanted to send a single packet. Given what you said here; however, larger packets will either undergo packetization (for TCP) or lost/fragmented (for UDP), so I would prefer to use TCP to send my larger packets and have them undergo "packetization" instead. 

Using packet.GetSize() on my packets returns roughly 490,000 and I would appreciate some help using TCP to send this data while using callbacks (I need to process the data when it reaches the server before sending packets back to the clients). I have tried to edit my existing code to using TCP,  which used UDP originally, but my callbacks do not work when switching. I have tried following the TCP documentation and I have tried to follow the TCP examples in examples/tcp/ but I am struggling converting this to Python and implementing the callbacks. I also tried setting the SetAcceptCallback and the SetRecvCallback for my sink socket following this discussion. Additionally, I have tried using cppyy to create the callbacks for SetAccept and SetRecv, but the Null callback (line 130) is not working. I do not know what would be going wrong on the channel, can you elaborate on this?

I have some code below which is used in my script that works with UDP:

    # BIND SINK AND SOCKET #
    tid = ns.TypeId.LookupByName("ns3::TcpSocketFactory")
    recv_sink = ns.Socket.CreateSocket(nodes.Get(sink_node.value), tid)
    local = ns.InetSocketAddress(ns.Ipv4Address.GetAny(), 80)
    recv_sink.Bind(local.ConvertTo())
    recv_sink.SetRecvCallback(ns.cppyy.gbl.server_callback(server_rx_packet))

    # CONNECT THE SOURCE NODES AND SOCKETS
    indexes = random.sample(list(range(num_nodes.value)), sample_num.value)
    for client in indexes:
        source = ns.Socket.CreateSocket(nodes.Get(client), tid)
        remote = ns.InetSocketAddress(interfaces.GetAddress(sink_node.value, 0), 80)
        source.Connect(remote.ConvertTo())
        source.SetRecvCallback(ns.cppyy.gbl.client_callback(client_rx_packet))
        send_packet = ns.cppyy.gbl.pythonMakeEvent(SendPacketClient, source, num_packets.value, ns.Time('5s'))
        ns.Simulator.Schedule(ns.Seconds(30.0), send_packet)


Notably, the bulk of my script follows the wifi-simple-adhoc-grid.cc example. 

I would greatly appreciate any help, thank you. Also, if this is the complete wrong approach, my apologies, I am still new to this software and would love to be pointed in the right direction.

Tommaso Pecorella

unread,
Sep 19, 2024, 3:00:39 AM9/19/24
to ns-3-users
I never use python, so I can't reliably help there.

However, mind that TCP is TCP - it doesn't send packets, it sends messages, and the boundary between messages is something you have to detect by yourself.

Explanation. Suppose that node A sends 450.000 bytes with one single Send (note: it might fail for the reasons below). The receiver socket will trigger the function bound by SetRecvCallback multiple times (a LOT of calls) with data size smaller than the original message (of course). It's the receiver's responsibility to understand when the message is over, and if there's another message afterwards. Note that two consecutive messages might be concatenated in the packetization...

A stupid strategy is to close the socket, which will trigger another callback (see SetCloseCallbacks), something that was done by HTTP 1.0, and - indeed - was super-inefficient.
A more intelligent way is to write in the message what's the message size, so that the receiver can rebuild it as a whole. Again, your responsibility to do it.

A final caveat. by reading the code (but I didn't test it), it seems that the upper limit is 128kB:
        TypeId("ns3::TcpSocket")
            .SetParent<Socket>()
            .SetGroupName("Internet")
            .AddAttribute(
                "SndBufSize",
                "TcpSocket maximum transmit buffer size (bytes)",
                UintegerValue(131072), // 128k
                MakeUintegerAccessor(&TcpSocket::GetSndBufSize, &TcpSocket::SetSndBufSize),
                MakeUintegerChecker<uint32_t>())

So you'll have to send your message using multiple calls - and also to check when you use Send that the call was - indeed - successful (check the Send function carefully).

BTW, also sending 128 kB at a time is idiotically inefficient because... well, this is kinda obvious and I'll leave to you to find out why.

ABDULJABBAR ALSHARIF

unread,
Sep 20, 2024, 7:26:02 PM9/20/24
to ns-3-...@googlegroups.com
hi , 
I would like to recommend using a wifi template which has a packet flow monitor to
divide total congestion error ...
Through a tutorial.

Jabbar

" if you want the rainbow you have deal with rains"




--
Posting to this group should follow these guidelines https://www.nsnam.org/wiki/Ns-3-users-guidelines-for-posting
---
You received this message because you are subscribed to the Google Groups "ns-3-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ns-3-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ns-3-users/34524be1-5adf-415c-bdb3-827f92c41705n%40googlegroups.com.

Synnove Svendsen

unread,
Oct 25, 2024, 7:58:09 PM10/25/24
to ns-3-users
Thank you guys for the responses. 

I have tried going back through my code and I have noted a few things. I realize that it is inefficient to send such large packets, and I will stray away from this idea. I have combed through my code and decided to start over to build the simulation in the "most" basic form and work my way up. Could you help me better understand my current code? Although you may not be as familiar with the Python implementation, I am hoping you can help me understand more of the underlying functionality.

I am trying to use TCP with the wifi-MAC in ad-hoc mode. I am trying to send a packet from my source to a sink node (simulating with only 2 nodes currently) where my sink uses a custom receive callback to indicate when it receives a packet. In using the ad-hoc mode, I followed the ad-hoc grid example to set up the simulation, but I could not get the receive callback to trigger. I checked the sockets where their status was (0) which, to my understanding, means the handshake is working between the source and the sink. From there, I tried using a flow monitor to see what the signals were doing. My flow monitor shows:

socket status: 0
Testing from node 0 to node 1

Sending Packets...

Flow 1: Source: 10.1.1.1 -> Sink: 10.1.1.2
  Tx Bytes: 108
  Rx Bytes: 108
  Bytes/Rx Packet: 54.0
  Lost Packets: 0
  Delay Sum: 0.012321336 s
Flow 2: Source: 10.1.1.2 -> Sink: 10.1.1.1
  Tx Bytes: 204
  Rx Bytes: 204
  Bytes/Rx Packet: 102.0
  Lost Packets: 0
  Delay Sum: 0.003006668 s


When looking at this, I thought the first flow corresponded to the handshake and the second was the packet transmission, but looking at the sources and sinks for these flows I am not certain that this is what is happening. Can you help me understand the flow monitor better? I would also like some help understanding why the server callback is not working as I would expect. 

Thank you.

Synnove Svendsen

unread,
Oct 25, 2024, 7:59:00 PM10/25/24
to ns-3-users
Forgot to attach the file, my apologies.
TCP_ADHOC_TRIAL.txt

Tommaso Pecorella

unread,
Oct 26, 2024, 3:57:37 AM10/26/24
to ns-3-users
Unfortunately I can't run python code right now, but I'd suggest to add a PCAP trace (the function is in the YansWifiPhyHelper).
Checking the PCAP with Wireshark will give you clues on what has been transmitted and received.
Reply all
Reply to author
Forward
0 new messages