Bugzilla – Bug 1729
NSC doesn't call the Send Callback
Last modified: 2013-11-13 10:40:08 UTC
Using the example "tcp-bulk-send.cc", and adding a internet.SetTcp ("ns3::NscTcpL4Protocol","Library",StringValue ("liblinux2.6.26.so")); line, it fails to work. BulkSendApplication::SendData() is called only once. And BulkSendApplication::DataSend is never called. BulkSendApplication uses m_socket->SetSendCallback ( MakeCallback (&BulkSendApplication::DataSend, this)); which I guess should make DataSend be called every time data is sent (since it will mean there is new free space in the buffer). This is with ns-3 3.17.
I just found bug#1711. It's basically the same, but for NSC instead of DCE.
I had a brief look at this and I think it needs to be looked at further. Here are some brief notes: There are two callbacks, "Send" callback and "DataSent" callback. Send pertains to the I/O flow control from user-space program to socket. "DataSent" callback is a non-standard (simulation-only) callback that is supposed to notify when bits hit the wire. The Nsc socket will buffer the data provided by the ns-3 application, and then tries to write into the NSC library. The below is from nsc-tcp-socket-impl.cc: 617 bool NscTcpSocketImpl::SendPendingData (void) ... 671 if (written > 0) 672 { 673 Simulator::ScheduleNow (&NscTcpSocketImpl::NotifyDataSent, this, ret); 674 return true; 675 } 676 return false; Here, when data is written from the ns-3 object into NSC's library, NotifyDataSent is called, but NotifySend is never called. I'm questioning both of these-- first, NotifyDataSent can't really be properly supported in this mode, because NSC stack code itself may hold the data for a while. Second, NotifySend probably needs to be called to enable flow control-- otherwise, the application needs to opportunistically guess or meter out its data to send to avoid overrunning the TCP buffers. I also wonder whether this used to work but was broken when the TCP code was refactored into TcpSocket -> TcpSocketBase (Nsc still uses TcpSocket)
The "Send" callback is clear. But to argue if the "DataSent" callback is correct (or correct enough) or not I guess we should know what the user case is. I can't see a single user of "DataSent" callback. So I can't say what the needs are.
(In reply to comment #3) > The "Send" callback is clear. But to argue if the "DataSent" callback is > correct (or correct enough) or not I guess we should know what the user case > is. > I can't see a single user of "DataSent" callback. So I can't say what the needs > are. This callback was proposed for simulation purposes, in case it was of use to log when bits were actually sent on the wire. It doesn't correspond to normal socket I/O. I'm not that concerned with that one since, as you said, the use case is not strong, but the Send() callback needs to work properly, IMO.
Created attachment 1709 [details] callback fix for bulk send application I ran into the same problem this bug report describes. For me the fix is simple: change the callbacks in the bulk send application from "Send" to "Sent". I think this is the actual intention of this kind of mechanism -- at least the comment suggests this: // We exit this loop when actual < toSend as the send side // buffer is full. The "DataSent" callback will pop when // some buffer space has freed ip. Please note the "DataSent" in the comment. I attached a patch to fix this issue.