OMNeT++ INET仿真框架开发手册——4 使用Sockets

4 使用Sockets

4.1 概述

INET Socket API 在标准 OMNeT++ 消息传递接口的基础上为多个通信协议提供了特殊的 C++ 抽象。

套接字最常用于应用程序和路由协议,以获取相应的协议服务。套接字能够与底层协议进行双向通信。它们可以组装和发送服务请求和数据包,也可以接收服务指示和数据包。

应用程序可以简单地调用套接字类的成员函数(如 bind()、connect()、send()、close())来创建和配置套接字,以及发送和接收数据包。应用程序还可以模拟使用多个不同的套接字。

下面几节首先介绍套接字的共享功能,然后详细列出所有 INET 套接字,主要是通过举例说明许多常见用法。


为简洁起见,本章中的代码片段有所简化。例如,省略了一些virtual修饰符和override限定符,并简化了一些算法以方便理解。

4.2 Socket接口

虽然套接字总是作为特定协议的 C++ 类来实现,但 INET 也提供了 C++ 套接字接口。这些接口允许编写通用的 C++ 代码,可以同时处理多种不同类型的套接字。

例如,所有套接字都实现了 ISocket 接口,所有网络协议套接字都实现了 INetworkSocket 接口。

4.3 识别Sockets

所有套接字都有一个套接字标识符,该标识符在网络节点内是唯一的。该标识符在套接字创建时自动分配给套接字。在套接字的整个生命周期内,都可以通过 getSocketId() 访问该标识符。

套接字标识符也在 SocketReq 和 SocketInd 数据包标记中传递。这些标记允许应用程序和协议识别Packet、Request和Indication所属的套接字。

4.4 配置Sockets

由于所有套接字都在hoods下进行消息传递,因此在使用前必须对其进行配置。为了将数据包和服务请求发送到底层通信协议的正确网关上,必须对输出网关进行配置:

socket.setOutputGate(gate("socketOut")); // configure socket output gate
socket.setCallback(this); // set callback interface for message processing

相反,底层通信协议的服务指示等传入信息可以在任何应用门上接收。

为了方便应用程序开发,所有套接字都支持存储用户指定的数据对象指针。该指针可通过 setUserData() 和 getUserData() 成员函数访问。

所有套接字的另一项必须配置是设置套接字Callback Interface。下一节将详细介绍Callback Interface。

还可使用其他Sockets特定的配置选项,这些选项将在相应Sockets的章节中讨论。

4.5 Callback Interface

为了便于集中处理信息,所有套接字都提供了一个Callback Interface,应用程序必须实现该接口。Callback Interface通常称为 ICallback,它被定义为其所属套接字的内部类。这些接口通常包含一些通用通知方法和几个套接字专用方法。

例如,最常见的回调方法是处理传入数据包的方法:

class ICallback // usually the inner class of the socket
{
    void socketDataArrived(ISocket *socket, Packet *packet);
};

4.6 处理消息

一般来说,套接字可以处理底层协议发送的所有传入信息。接收到的信息必须由其所属的套接字处理。

例如,应用程序可以简单地以任意顺序浏览每个Socket,并决定由哪个Socket来处理接收到的信息,如下所示:

if (socket.belongsToSocket(message)) // match message and socket
    socket.processMessage(message); // invoke callback interface

套接字通常会对接收到的信息进行解构,并在必要时更新其状态。套接字还会自动将接收到的数据包和服务指示分派给相应 ICallback 接口中的适当函数,以便进一步处理。

4.7 发送数据

所有套接字都提供一个或多个 send() 函数,使用套接字的当前配置发送数据包。数据包的实际发送方式取决于底层通信协议,但一般来说,套接字的状态会对其产生影响。

例如,套接字配置妥当后,应用程序无需附加任何标签即可开始发送数据包,因为套接字会处理必要的技术细节:

socket.send(packet); // by means of the underlying communication protocol

4.8 接收数据

例如,应用程序可以直接实现套接字的 ICallback 接口,并打印接收到的数据,如下所示:

class App : public cSimpleModule, public ICallback
{
    void socketDataArrived(ISocket *socket, Packet *packet);
};

void App::socketDataArrived(ISocket *socket, Packet *packet)
{
    EV << packet->peekData() << endl;
}

4.9 关闭Socket

在删除套接字之前,必须先关闭套接字。关闭套接字允许底层通信协议释放已分配的资源。这些资源通常分配在本地网络节点、远程网络节点或网络的其他地方。

例如,面向连接协议的套接字必须关闭,以释放对等方分配的资源:

socket.close(); // release allocated local and remote network resources

4.10 使用多个Socket

如果应用程序需要管理大量Socket,例如在处理多个传入连接的服务器应用程序中,通用 SocketMap 类可能会很有用。该类可以同时管理各种实现 ISocket 接口的套接字。

例如,处理传入数据包或服务指示的步骤如下:

auto socket = socketMap.findSocketFor(message); // lookup socket to process
socket->processMessage(message); // dispatch message to callback interface

为了使 SocketMap 正常运行,必须使用 addSocket() 和 removeSocket() 方法分别向其中添加和删除套接字。

4.11 UDP Socket

UdpSocket 类为发送和接收 UDP 数据报提供了一个易于使用的 C++ 接口。底层 UDP 协议在 Udp 模块中实现。

4.11.1 Callback Interface

处理从 Udp 模块接收到的数据包和指示非常简单。如常规部分所示,传入的信息必须由其所属的套接字处理。

UdpSocket 会解构报文,并使用 UdpSocket::ICallback 接口通知应用程序已收到的数据和错误指示:

class ICallback // inner class of UdpSocket
{
    void socketDataArrived(UdpSocket *socket, Packet *packet);
    void socketErrorArrived(UdpSocket *socket, Indication *indication);
};
4.11.2 配置Sockets

要在套接字上接收 UDP 数据报,必须将其与地址和端口绑定。地址和端口都是可选的。如果地址未指定,则接收所有目标地址的 UDP 数据报。如果端口为-1,则 Udp 模块会自动选择一个未使用的端口。在同一网络节点内,地址和端口必须是唯一的。

以下是绑定到特定本地地址和端口以接收 UDP 数据报的方法:

socket.bind(Ipv4Address("10.0.0.42"), 42); // local address/port

如果只接收来自特定远程地址/端口的 UDP 数据报,可将套接字连接到所需的远程地址/端口:

socket.connect(Ipv4Address("10.0.0.42"), 42); // remote address/port

还有其他一些套接字选项(如接收广播、管理多播组、设置服务类型)也可以使用 UdpSocket 类进行配置:

socket.setTimeToLive(16); // change default TTL
socket.setBroadcast(true); // receive all broadcasts
socket.joinMulticastGroup(Ipv4Address("224.0.0.9")); // receive multicasts
4.11.3 发送数据

套接字配置完成后,应用程序就可以通过简单的函数调用向远程地址和端口发送数据报:

socket.sendTo(packet42, Ipv4Address("10.0.0.42"), 42); // remote address/port

如果应用程序要发送多个数据报,可以选择连接目的地。

UDP 协议实际上是无连接协议,因此当 Udp 模块收到连接请求时,它只会记住远程地址和端口,并将其作为以后发送的默认目的地。

socket.connect(Ipv4Address("10.0.0.42"), 42); // remote address/port
socket.send(packet1); // send packets via connected socket
// ...
socket.send(packet42);

应用程序可以在同一个套接字上多次调用 connect。

4.11.4 接收数据

例如,应用程序可以直接实现 UdpSocket::ICallback 接口,并打印接收到的数据如下:

class UdpApp : public cSimpleModule, public UdpSocket::ICallback
{
    void socketDataArrived(UdpSocket *socket, Packet *packet);
};

void UdpApp::socketDataArrived(UdpSocket *socket, Packet *packet)
{
    EV << packet->peekData() << endl;
}

4.12 TCP Socket

TcpSocket 类提供了一个易于使用的 C++ 接口,用于管理 TCP 连接以及发送和接收数据。底层 TCP 协议在 Tcp、TcpLwip 和 TcpNsc 模块中实现。

4.12.1 Callback Interface

从各种 Tcp 模块接收的信息可由其所属的 TcpSocket 处理。TcpSocket 会解构报文,并使用 TcpSocket::ICallback 接口将收到的数据或服务指示通知应用程序:

class ICallback // inner class of TcpSocket
{
    void socketDataArrived(TcpSocket* socket, Packet *packet, bool urgent);
    void socketAvailable(TcpSocket *socket, TcpAvailableInfo *info);
    void socketEstablished(TcpSocket *socket);
    // ...
    void socketClosed(TcpSocket *socket);
    void socketFailure(TcpSocket *socket, int code);
};
4.12.2 配置连接

Tcp 模块支持多种不同的 TCP 拥塞算法,这些算法也可以使用 TcpSocket 进行配置:

socket.setTCPAlgorithmClass("TcpReno");

设置好各个参数后,套接字会立即向底层 Tcp 协议模块发送设备请求。

4.12.3 设置连接

由于 TCP 是一种面向连接的协议,因此在应用程序交换数据之前必须先建立连接。一方面,应用程序通过本地地址和端口监听传入的 TCP 连接:

socket.bind(Ipv4Address("10.0.0.42"), 42); // local address/port
socket.listen(); // start listening for incoming connections

在另一端,应用程序连接到远程地址和端口,建立新的连接:

socket.connect(Ipv4Address("10.0.0.42"), 42); // remote address/port
4.12.4 接受连接

Tcp 模块会自动通知 TcpSocket 有关传入连接的信息。套接字反过来使用回调接口的 ICallback::socketAvailable 方法通知应用程序。最后,传入的 TCP 连接必须被应用程序接受后才能使用:

class TcpServerApp : public cSimpleModule, public TcpSocket::ICallback
{
    TcpSocket serverSocket; // server socket listening for connections
    SocketMap socketMap; // container for all accepted connections

    void socketAvailable(TcpSocket *socket, TcpAvailableInfo *info);
};

void TcpServerApp::socketAvailable(TcpSocket *socket, TcpAvailableInfo *info)
{
    auto newSocket = new TcpSocket(info); // create socket using received info
    // ...
    socketMap.addSocket(newSocket); // store accepted connection
    serverSocket.accept(info->getNewSocketId()); // notify Tcp module
}

连接被接受后,Tcp 模块会通知应用程序套接字已建立并准备就绪。

4.12.5 发送数据

连接建立后,应用程序可通过简单的函数调用向远程应用程序发送数据:

socket.send(packet1);
// ...
socket.send(packet42);

数据包数据由本地 Tcp 模块排序,并根据协议逻辑分时段传输。

4.12.6 接收数据

接收数据就像实现 TcpSocket::ICallback 接口的相应方法一样简单。需要注意的是,由于 TCP 协议的特性,数据包数据到达时的块大小可能与发送时不同(但顺序相同)。

例如,应用程序可以直接实现 TcpSocket::ICallback 接口,并打印接收到的数据,如下所示:

class TcpApp : public cSimpleModule, public TcpSocket::ICallback
{
    void socketDataArrived(TcpSocket *socket, Packet *packet, bool urgent);
};

void TcpApp::socketDataArrived(TcpSocket *socket, Packet *packet, bool urgent)
{
    EV << packet->peekData() << endl;
}
目 录 第一章 无线传感器网络概述 6 概述 6 1.1 NS-2 6 1.2 OPNET 6 1.3 SensorSim 7 1.4 EmStar 7 1.5 GloMoSim 7 1.6 TOSSIM 7 1.7 PowerTOSSIM 8 第二章 OMNET++简介 9 概述 9 2.1 OMNeT++框架 9 2.1.1 OMNeT++组成 9 2.1.2 OMNeT++结构 10 2.2 OMNeT++的安装 11 2.3 OMNeT++语法 12 2.3.1 NED语言 12 2.3.1.1 NED总概述 12 2.3.1.2 Ned描述的组件 13 2.3.1.3函数 15 2.3.2 简单模块 17 2.3.2.1 OMNET++中离散事件 17 2.3.2.2 包传输模型 17 2.3.2.3定义简单模块 18 2.3.2.4 简单模块中的主要成员函数 20 2.3.3 消息 21 2.3.3.1 cMessage类 21 2.3.3.2 消息定义 21 2.3.3.3 消息的收发 22 2.3.4 模块参数、门及连接的访问 23 2.3.4.1消息参数的访问 23 2.3.4.2门和连接的访问 24 2.3.4.3门的传输状态 26 2.3.3.4连接的状态 26 2.4 仿真过程 27 2.5 配置文件omnetpp.ini 28 2.6 结果分析工具 29 2.6.1 矢量描绘工具Plove 29 2.6.2 标量工具Scalar 29 27、结束语 30 第三章 物理层仿真(信道) 32 3.1 UWB的基础知识 32 3.1.1 UWB信号的应用背景 32 3.1.2 UWB信号的定义 32 3.1.3 UWB的脉冲生成方式(高斯脉冲,非高斯脉冲) 34 3.1.4 UWB的调制方式 34 3.1.5 用功率控制多址接入方法来进行链路的建立控制 36 3.2 用OMNeT++对UWB进行仿真 37 3.2.1 算法仿真的概述 37 3.2.2 算法的具体流程 39 3.2.3 算法的主要代码 41 3.2.4 仿真结果分析 58 3.2.5 应用前景 58 参考文献 59 第四章 MAC层仿真 60 概述 60 4.1 无线传感器网络MAC层特性及分类 60 4.1.1 无线信道特性 60 4.1.2 MAC 设计特性分析 61 4.1.3 无线传感器网络典型MAC协议的分类 61 4.2 基于随机竞争的MAC协议 62 4.2.1 S-MAC协议[12] 62 4.2.2 T-MAC协议 64 4.2.3 AC-MAC协议 65 4.3 基于时分复用的MAC协议 65 4.3.1 D-MAC协议 65 4.3.2 TRAMA协议 66 4.3.3 AI-LMAC协议 66 4.4 其他类型的MAC协议 67 4.4.1 SMACS/EAR协议 67 4.4.2 基于CDMA技术的MAC协议 67 4.4.3 DCC-MAC 68 4.5 基于OMNeT++的MAC层协议仿真 69 4.5.1 S-MAC协议的仿真 69 4.5.2 S-MAC协议流程图 70 4.5.3 S-MAC协议的分析 71 4.6 小结 86 参考文献 86 第五章 网络仿真 88 概述 88 5.1 无线传感器网络路由协议研究 88 5.1.1 无线传感器网络协议分类 88 5.1.2无线传感器网络中平面路由 90 5.1.3无线传感器网络中层次化路由 91 5.1.4 经典算法的OMNET仿真 93 5.2 无线传感器网络路由协议研究的发展趋势 104 5.3 无线传感器网络层路由协议与OMNET++仿真 104 5.3.1 无线传感器网络层路由与OMNET++仿真的基本概念[19] 104 5.3.1.1 传感器网络的体系结构 105 5.3.1.1.1 传感节点的物理结构 105 5.3.1.1.2 传感器网络的体系结构与网络模型 106 5.3.2 传感器网络层路由协议的基本概念 106 5.3.2.1 网络通信模式[28] 106 5.3.2.1.1 单播: 107 5.3.2.1.2 广播: 107 5.3.2.1.3 组播: 108 5.3.2.2传感器网络层设计[29] 108 5.3.3 OMNET++仿真软件的基本概念 109 5.4 无线传感器网络路由协议介绍 110 5.4.1 泛洪法(Flooding)[32] 111 5.4.2 定向扩散(Directed Diffusion:DD)[33] 112 5.4.3 LEACH( Energy Adaptive Clustering Hierarchy)[34] 113 5.5. OMNET++仿真实例 114 5.5.1 泛洪法 114 5.5.2 gossiping协议 119 5.6 本章总结 121 参考文献 121 第六章 应用层仿真 125 6.1 无线传感器网络节点定位 125 6.1.1 节点定位的基本概念 125 6.1.1.1 节点定位的定义 125 6.1.1.2 节点定位的重要性 126 6.1.2 节点定位的研究 126 6.1.2.1 测距方法 126 6.1.2.2 节点定位原理 127 6.1.2.3 节点定位算法分类 128 6.1.2.3.1 锚节点分类 128 6.1.2.3.2 计算方式分类 129 6.1.2.3.3 测距分类 130 6.1.2.3.4 节点移动性分类 130 6.1.2.4 节点定位性能评价[37] 130 6.1.3基于OMNET++的DV—Hop定位算法仿真 132 6.1.3.1 DV—Hop定位算法的基本思想 132 6.1.3.2 DV—Hop定位算法仿真 133 6.2 网络管理 141 6.2.1概叙 141 6.2.1.1 wsn网络管理的定义及范畴 142 6.2.1.2 wsn网络管理系统的分类 143 6.2.1.3 wsn网络管理系统的设计标准 144 6.2.2 wsn网络管理系统 145 6.2.2.1 能量管理系统 145 6.2.2.1.1 SenOs[5] 145 6.2.2.2 拓扑控制系统 146 6.2.2.2.1 TopDisc 算法 146 6.2.2.3 可调试、可配置、可编程系统 148 6.2.2.2.1 sympathy 系统[42] 148 6.2.2.2.2 Agilla系统[7] 149 6.2.3典型网络管理算法的Omnet 模拟 150 6.2.3.1 基于Wsn的一个简单拓扑查找算法算法模拟 150 6.2.4 结论 155 6.3 基于路由层安全协议的OMNeT++仿真 156 6.3.1 基础知识介绍 156 6.3.1.1无线传感器网络安全性的重要性和必要性 156 6.3.1.2 无线传感器网络的安全目标 156 6.3.1.3无线传感器网络中的路由协议概述 157 6.3.1.4无线传感器网络路由协议的攻击方法 157 6.3.1.5无线传感器网络中经典路由协议安全性分析 160 6.3.1.6 安全路由技术分析 162 6.3.1.6.1 密钥管理技术[20, 23, 24, 25] 162 6.3.1.6.2 安全路由协议 162 6.3.2 在OMNeT++ 中的仿真 163 6.3.3 总结 172 参考文献 172 第七章 实例(无线传感器网络移动节点定位仿真) 179 概述 179 7.1 移动定位算法介绍 179 7.1.1 室内移动节点定位算法 179 7.1.1.1 Active Badge系统 180 7.1.1.2 RADAR系统 180 7.1.1.3 Cricket系统 180 7.1.2 室外移动节点定位算法 181 7.1.2.1 基于静态定位的移动定位算法 181 7.1.2.2 纯移动定位算法 182 7.2 移动定位算法的OMNeT++仿真 183 7.2.1 MCL(Monte Carlo Localization)定位算法简介 183 7.2.2 MCL(Monte Carlo Localization)的OMNeT++仿真 185 7.2.2.1 建立网络拓扑 185 7.2.2.2 编码阶段 190 7.3.总结和发展趋势 195 参考文献 195
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值