ns-3应用层协议
应用层协议有两个要点:
- 使用Socket建构分组处理流程
- 使用Application封装
Socket原语函数
ns-3的Socket原语函数基本参照了POSIX的Socket函数,使用的时候参考POSIX的Socket编程经验即可。
和POSIX一样,这里的Socket也采用异步IO的编程模式,所以还需要设置回调函数。
Socket回调函数
原语函数有对应的回调设置函数如下:
Socket原语函数调用后会直接返回应用层,而不必等待调用的结果;操作结果出来后,下层协议会调用Socket提供的函数指针触发应用层回调函数将执行结果通知应用层协议。
举例:一个TCP连接建立的过程
int main(int argc, char *argv[])
{
//1
Ptr<Socket> serverSocket = Socket::CreateSocket(nodes.Get(1), TcpSocketFactory::GetTypeId());
Ptr<Socket> clientSocket = Socket::CreateSocket(nodes.Get(0), TcpSocketFactory::GetTypeId());
//2
Simulator::ScheduleNow(&setServerSocket, serverSocket, port);
Simulator::Schedule(Seconds(1.0), &startFlow, clientSocket, Ipv4Address("10.1.1.2"), port);
//3
Simulator::Schedule(Seconds(10.0), &close, clientSocket);
Simulator::Schedule(Seconds(11.0), &close, serverSocket);
Simulator::Stop(Seconds(12.0));
Simulator::Run();
Simulator::Destory();
}
- 创建C/S两端的Socket对象,使用工厂方法;
- 使用Socket原语函数创建TCP连接并配置回调函数;
- 设置Socket关闭时间。
上面2中设置的回调函数
void setServerSocket(Ptr<Socket> serverSocket, uint32_t localPort)
{
serverSocket->Bind(InetSocketAddress(Ipv4Address::GetAny(), localPort));
serverSocket->Listen();
serverSocket->SetRecvCallback(MakeCallback(&receivedData));
serverSocket->SetAcceptCallback(MakeNullCallback<bool, Ptr<Socket>, const Address&>(), MakeCallback(&handleAccept));
}
void startFlow(Ptr<Socket> clientSocket, Ipv4Address dstAddr, uint32_t dstPort)
{
clientSocket->Bind();
clientSocket->Connect(InetSocketAddress(dstAddr, dstPort));
clientSocket->SetConnectCallback(MakeCallback(&connectionSucceeded), MakeNullCallback<void, Ptr<Socket>());
}
- 服务器调用Bind和Listen绑定和监听本地Socket端口
- 客户端调用Bind和Connect指定服务器端口和发起TCP握手
Application类
可以参考:
src/application/model
src/internet-app/model
examples/tutorial/fifth.cc
主要介绍两个函数:
- StartApplication 在Application启动时间到时被自动调用,一般Socket的原语和回调设置都在这个函数里面;
- Stop Application 在Application停止时间到时被自动调用,一般Close原语和关闭套接字的函数在这个函数里。