|
|
| 47 |
using namespace ns3; |
47 |
using namespace ns3; |
| 48 |
|
48 |
|
| 49 |
NS_LOG_COMPONENT_DEFINE ("TcpLargeTransfer"); |
49 |
NS_LOG_COMPONENT_DEFINE ("TcpLargeTransfer"); |
|
|
50 |
static uint32_t txBytes = 2000000; // number of bytes to send to peer |
| 50 |
|
51 |
|
| 51 |
void |
52 |
void |
| 52 |
ApplicationTraceSink (Ptr<const Packet> packet, |
53 |
ApplicationTraceSink (Ptr<const Packet> packet, |
|
|
| 78 |
} |
79 |
} |
| 79 |
|
80 |
|
| 80 |
void CloseConnection (Ptr<Socket> localSocket); |
81 |
void CloseConnection (Ptr<Socket> localSocket); |
| 81 |
void StartFlow(Ptr<Socket>, uint32_t, Ipv4Address, uint16_t); |
82 |
void StartFlow(Ptr<Socket>, Ipv4Address, uint16_t); |
| 82 |
void WriteUntilBufferFull (Ptr<Socket>, uint32_t); |
83 |
void WriteUntilBufferFull (Ptr<Socket>, uint32_t); |
| 83 |
|
84 |
|
| 84 |
int main (int argc, char *argv[]) |
85 |
int main (int argc, char *argv[]) |
|
|
| 139 |
// |
140 |
// |
| 140 |
/////////////////////////////////////////////////////////////////////////// |
141 |
/////////////////////////////////////////////////////////////////////////// |
| 141 |
|
142 |
|
| 142 |
int nBytes = 2000000; |
|
|
| 143 |
uint16_t servPort = 50000; |
143 |
uint16_t servPort = 50000; |
| 144 |
|
144 |
|
| 145 |
// Create a packet sink to receive these packets |
145 |
// Create a packet sink to receive these packets |
|
|
| 153 |
//TypeId tid = TypeId::LookupByName ("ns3::TcpSocketFactory"); |
153 |
//TypeId tid = TypeId::LookupByName ("ns3::TcpSocketFactory"); |
| 154 |
Ptr<Socket> localSocket = Socket::CreateSocket (c0.Get (0), TcpSocketFactory::GetTypeId ()); |
154 |
Ptr<Socket> localSocket = Socket::CreateSocket (c0.Get (0), TcpSocketFactory::GetTypeId ()); |
| 155 |
localSocket->Bind (); |
155 |
localSocket->Bind (); |
| 156 |
Simulator::ScheduleNow (&StartFlow, localSocket, nBytes, |
156 |
Simulator::ScheduleNow (&StartFlow, localSocket, |
| 157 |
ipInterfs.GetAddress (1), servPort); |
157 |
ipInterfs.GetAddress (1), servPort); |
| 158 |
|
158 |
|
|
|
159 |
//localSocket->SetAttribute("SndBufSize", UintegerValue(4096)); |
| 159 |
Config::ConnectWithoutContext ("/NodeList/*/ApplicationList/*/Rx", |
160 |
Config::ConnectWithoutContext ("/NodeList/*/ApplicationList/*/Rx", |
| 160 |
MakeCallback (&ApplicationTraceSink)); |
161 |
MakeCallback (&ApplicationTraceSink)); |
| 161 |
|
162 |
|
|
|
| 170 |
Simulator::Destroy (); |
171 |
Simulator::Destroy (); |
| 171 |
} |
172 |
} |
| 172 |
|
173 |
|
| 173 |
void CloseConnection (Ptr<Socket> localSocket) |
174 |
void StartFlow(Ptr<Socket> localSocket, |
| 174 |
{ |
|
|
| 175 |
localSocket->Close (); |
| 176 |
} |
| 177 |
|
| 178 |
void StartFlow(Ptr<Socket> localSocket, uint32_t nBytes, |
| 179 |
Ipv4Address servAddress, |
175 |
Ipv4Address servAddress, |
| 180 |
uint16_t servPort) |
176 |
uint16_t servPort) |
| 181 |
{ |
177 |
{ |
| 182 |
// NS_LOG_LOGIC("Starting flow at time " << Simulator::Now ().GetSeconds ()); |
178 |
// NS_LOG_LOGIC("Starting flow at time " << Simulator::Now ().GetSeconds ()); |
| 183 |
localSocket->Connect (InetSocketAddress (servAddress, servPort));//connect |
179 |
localSocket->Connect (InetSocketAddress (servAddress, servPort));//connect |
| 184 |
localSocket->SetConnectCallback (MakeCallback (&CloseConnection), |
180 |
|
| 185 |
Callback<void, Ptr<Socket> > ()); |
181 |
// tell the tcp implementation to call WriteUntilBufferFull again |
| 186 |
//we want to close as soon as the connection is established |
182 |
// if we blocked and new tx buffer space becomes available |
| 187 |
//the tcp state machine and outgoing buffer will assure that |
|
|
| 188 |
//all of the data is delivered |
| 189 |
localSocket->SetSendCallback (MakeCallback (&WriteUntilBufferFull)); |
183 |
localSocket->SetSendCallback (MakeCallback (&WriteUntilBufferFull)); |
| 190 |
WriteUntilBufferFull (localSocket, nBytes); |
184 |
WriteUntilBufferFull (localSocket, txBytes); |
| 191 |
} |
185 |
} |
| 192 |
|
186 |
|
| 193 |
void WriteUntilBufferFull (Ptr<Socket> localSocket, uint32_t nBytes) |
187 |
void WriteUntilBufferFull (Ptr<Socket> localSocket, uint32_t txSpace) |
| 194 |
{ |
188 |
{ |
| 195 |
// Perform series of 1040 byte writes (this is a multiple of 26 since |
189 |
// Perform series of 1040 byte writes (this is a multiple of 26 since |
| 196 |
// we want to detect data splicing in the output stream) |
190 |
// we want to detect data splicing in the output stream) |
| 197 |
uint32_t writeSize = 1040; |
191 |
uint32_t writeSize = 1040; |
| 198 |
uint8_t data[writeSize]; |
192 |
uint8_t data[writeSize]; |
| 199 |
while (nBytes > 0) { |
193 |
|
| 200 |
uint32_t curSize= nBytes > writeSize ? writeSize : nBytes; |
194 |
while (txBytes > 0) { |
|
|
195 |
uint32_t curSize= txBytes > writeSize ? writeSize : txBytes; |
| 196 |
if (curSize > txSpace) |
| 197 |
curSize = txSpace; |
| 201 |
for(uint32_t i = 0; i < curSize; ++i) |
198 |
for(uint32_t i = 0; i < curSize; ++i) |
| 202 |
{ |
199 |
{ |
| 203 |
char m = toascii (97 + i % 26); |
200 |
char m = toascii (97 + i % 26); |
| 204 |
data[i] = m; |
201 |
data[i] = m; |
| 205 |
} |
202 |
} |
| 206 |
uint32_t amountSent = localSocket->Send (data, curSize, 0); |
203 |
int amountSent = localSocket->Send (data, curSize, 0); |
| 207 |
if(amountSent < curSize) |
204 |
if(amountSent < 0) |
| 208 |
{ |
205 |
{ |
| 209 |
std::cout << "Socket blocking, returning" << std::endl; |
206 |
// we will be called again when new tx space becomes available. |
|
|
207 |
std::cout << "Socket blocking, " << txBytes << " left to write, returning" << std::endl; |
| 210 |
return; |
208 |
return; |
| 211 |
} |
209 |
} |
| 212 |
nBytes -= curSize; |
210 |
txBytes -= curSize; |
|
|
211 |
if (amountSent != (int)curSize) |
| 212 |
{ |
| 213 |
std::cout << "Short Write, returning" << std::endl; |
| 214 |
return; |
| 215 |
} |
| 213 |
} |
216 |
} |
|
|
217 |
localSocket->Close (); |
| 214 |
} |
218 |
} |