null 第9章 UDP程序设计人民邮电出版社 第9章 UDP程序设计9.1 UDP网络程序设计模型9.1 UDP网络程序设计模型9.1.1 UDP程序工作
流程
快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计
根据前面介绍的知识我们知道,TCP
协议
离婚协议模板下载合伙人协议 下载渠道分销协议免费下载敬业协议下载授课协议下载
是基于数据流形式进行数据传输的,而UDP协议是基于数据报模式进行数据传输的。它的通信双方是不需要建立连接的,对于一些速度要求较高可靠性要求不高的网络应用程序来说,数据报通信是一个非常好的选择 。
数据报是网络层数据单元在介质上传输信息的一种逻辑分组格式,它是一种在网络中传播的、独立的、自身包含地址和端口号信息的消息,它能否到达目的地、到达的时间、到达时
内容
财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容
是否会变化不能准确地知道。
无连接的数据报(SOCK_DGRAM)传输服务在传输层使用UDP协议,与面向连接的通信过程不同,它的最大特点是不需要在客户和服务器之间先建立连接。通信的任何一方可以先发送数据,这样首先发送数据的一方就成了客户端,而接收数据的一方就是服务器端。在数据传输完成后,只要关闭套接口释放网络资源,通信过程就结束了。9.1 UDP网络程序设计模型9.1 UDP网络程序设计模型9.1.1 UDP程序工作流程
无连接的数据报传输服务通信时,客户端与服务器端所使用的函数是类似的。其工作流程如下:
第一步:使用WSAStartup()函数检查系统协议栈的安装情况。常用格式为:
WSAStartup(0x0202,&wsaData);
WSAStartup(MAKEWORD(2,2),&wsaData);
第二步:使用socket()或WSASocket()函数创建套接口,以确定了相关五元组的协议。常用格式有如下几种:9.1 UDP网络程序设计模型9.1 UDP网络程序设计模型9.1.1 UDP程序工作流程
SOCKET s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
SOCKET s=socket(AF_INET,SOCK_DGRAM,0);
SOCKET s=WSASocket(AF_INET,SOCK_DGRAM,IPPROTO_TCP,NULL,0,WSA_FLAG_OVERLAPPED);
SOCKET s=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_OVERLAPPED);9.1 UDP网络程序设计模型9.1 UDP网络程序设计模型9.1.1 UDP程序工作流程
第三步:使用bind()函数将创建的套接口与本地地址绑定。它确定了相关五元组中的本地IP地址和端口号。
常用格式:bind(s,(const struct sockaddr*)&localaddr,sizeof(sockaddr));
第四步:使用sendto()或WSASendTo()函数发送数据,也可使用recvfrom()或WSARecvFrom()函数接收数据。
第五步:使用closesocket()函数关闭套接口。
第六步:最后调用WSACleanup()函数,结束Windows Sockets API的使用。
至此,一次无连接的数据报传输过程结束。9.1 UDP网络程序设计模型9.1 UDP网络程序设计模型9.1.2 程序框架
无连接的客户与服务器之间的交互通信模型可以图9-1表示。
9.1 UDP网络程序设计模型9.1 UDP网络程序设计模型9.1.2 程序框架
图9-1所示的通信模型也明确的表示出了无连接的客户机/服务器程序框架,图中在进行数据交换时,双方均可以发送数据和接收数据。
在具体编写无连接的客户机/服务器程序时,应该注意以下几个问
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
:
通信的一方可以不用bind()绑定IP地址和端口,而由系统自动分配,但要注意不绑定IP地址和端口的一方必须首先向绑定地址的一方发送数据。
无连接应用程序也可以调用connect()函数,但是它并不向对方发出建立连接的请求,内核只是将connect()中指定的目标端IP地址和端口号记录下来,在以后的通信中就可以使用面向连接的数据发送send()和数据接收revc()函数。9.1 UDP网络程序设计模型9.1 UDP网络程序设计模型9.1.2 程序框架
无连接的数据报传输过程中,做为服务器的一方必须要先启动,否则客户请求传不到服务进程。
由于无连接的客户端一般不调用connect(),因此在数据发送之前,客户与服务器之间尚未建立一个全相关(五元组),但各自通过socket()和bind()调用建立了半相关。发送数据时,发送方除指定本地套接口的地址外,还需指定接收方套接口的地址,从而在数据收发过程中动态地建立了全相关。9.2 UDP实例程序19.2 UDP实例程序1实例程序说明
本实例程序使用的编程环境为Visual C++6.0,使用的是控制台程序“Win32 Console Application”。通信协议使用无连接的UDP协议(SOCK_DGRAM)。服务器端IP地址由系统指定,端口号在程序中指定为5050,用符号常量定义。
编该实例中我们编写一个基于数据报的客户机/服务器交互程序,在程序启动后,服务器向客户端发送“Hello!I am a server.”信息,客户端向服务器发送“Hello!I am a client.”信息,双方各自在接收到对方发送的信息后将其显示出来。
图9-2是服务器端程序执行后的结果。服务器程序在启动后等待客户机的请求,如果有客户机请求后,它将向客户机发送信息“Hello!I am a server.”,并收到由客户机发送的信息“Hello!I am a client.”。9.2 UDP实例程序19.2 UDP实例程序19.2 UDP实例程序19.2 UDP实例程序1从图9-2中可以看出,服务器收到了两个客户的请求。
图9-3是客户端程序执行后的窗口。客户端程序执行时,从键盘输入服务器的IP地址(即在命令行中输入),客户端口号由系统指定,服务器端口号指定为5050。第一次执行时没有输入服务器的IP地址,则显示命令用法后返回。第二次执行时输入正确的命令行格式,则显示数据成功发送的提示信息,然后显示从服务器收到的信息。服务器则显示从客户收到的信息“Hello! I am a client.”,然后显示客户的IP地址和端口号,最后显示数据成功发送的提示信息。第三次执行时也输入了正确的命令行格式,但注意服务器所显示的端口号与前一次执行时不同(如图9-2所示),因为客户机的端口号由系统自动分配。
9.2 UDP实例程序19.2 UDP实例程序1
9.3 UDP实例程序29.3 UDP实例程序2
9.3.1 程序要求
在本节中,我们实现一个名叫Echo的协议(有些
资料
新概念英语资料下载李居明饿命改运学pdf成本会计期末资料社会工作导论资料工程结算所需资料清单
中叫回声协议)。Echo协议是一个非常简单的协议,它主要用于网络可达性的检测中。Echo协议的功能也十分简单,服务器在端口7检测接收到的信息,如果收到信息,则原封不动的重发回客户端。Echo协议工作时可以基于TCP协议,也可以基于UDP协议。本节我们实现基于UDP协议的Echo协议。9.3 UDP实例程序29.3 UDP实例程序2
服务器端程序运行的窗口如图9-4所示,图中有3个客户端进行了请求。
图9-4 Echo服务器运行结果
9.3 UDP实例程序29.3 UDP实例程序2Echo客户端程序运行结果如图9-5所示,图中客户端程序运行了3次。从图9-5中可以看出,客户端计算机输入的内容被Echo服务器原封不动的返回。
图9-5 Echo客户端程序运行结果
9.3 UDP实例程序29.3 UDP实例程序2
9.3.2 服务器程序
在设计服务器端程序之前,我们先来讨论一下在Java语言中与数据报程序设计有关的知识。数据报按用途我们可以将其分为两种:一种用来发送数据,该数据报要给出目的地址和端口号;另一种数据报用来从网络中接收数据。不管是发送或者接收UDP数据报,首先需要创建数据报套接口。
1. 创建数据报套接口的DatagramSocket类
在Java语言里,数据报套接口由类java.net.DatagramSocket实现。
在TCP程序设计中,我们使用Socket创建一个客户端套接口,使用ServerSocket创建一个服务器套接口;但在Java的UDP程序设计中,DatagramSocket创建的套接口既可用于UDP客户端程序也可用于UDP服务器程序。9.3 UDP实例程序29.3 UDP实例程序2
9.3.2 服务器程序
DatagramSocket类常用的构造方法有:
public DatagramSocket() throws SocketException
public DatagramSocket(int port) throws SocketException
public DatagramSocket(int port, InetAddress laddr) throws SocketException
其中,构造方法中的port参数用于指定DatagramSocket绑定的端口,如果不指定port,系统自动为数据报套接口选择一个可用端口。以上带有两个参数的第3个构造方法创建一个数据报套接口,并将其绑定到指定的本地地址,这主要用于多IP地址的主机中。在上面的构造方法中,如果不能创建套接口或套接口无法绑定到指定的端口,则抛出SocketException异常。9.3 UDP实例程序29.3 UDP实例程序2
9.3.2 服务器程序
DatagramSocket类中定义的几个常用方法是:
public void send(DatagramPacket p) throws IOException:从当前数据报套接口发送一个数据报。发送数据报应包含将要发送的数据、数据长度、目标主机IP地址和目标主机端口号等信息。
public void receive(DatagramPacket p) throws IOException:从当前数据报套接口接收一个数据报。接收到的数据报中包含发送方的主机IP地址、端口号等信息。
public void close():关闭数据报套接口,释放其占有的系统资源。9.3 UDP实例程序29.3 UDP实例程序2
9.3.2 服务器程序
需要注意的是调用receive()方法,它将阻塞当前Java线程,直到其能收到数据报才返回。我们可以调用方法setSoTimeout(int timeout)设置阻塞时间,时间的单位为毫秒。当等待时间到达阻塞时间时,receive()方法就返回并抛出SocketTimeoutException异常。当调用close()关闭数据报套接口时,被阻塞的receive()调用也会因IOException异常而返回。9.3 UDP实例程序29.3 UDP实例程序2
9.3.2 服务器程序
2. 创建UDP数据报的DatagramPacket类
Java.net包中的DategramPacket类用来创建UDP数据报,创建接收数据报的构造方法是:
public DatagramPacket(byte[] buf, int length)
public DatagramPacket(byte[] buf, int offset, int length)
其中,参数buf表示保存传入数据报的缓冲区,length表示希望接收到的数据报的最大长度,第二个构造方法中的offset参数,指定了缓冲区的偏移量,表示数据从buf[offset]开始存储。9.3 UDP实例程序29.3 UDP实例程序2
9.3.2 服务器程序
下面的语句创建了一个接收缓冲区长度为8912个字节的UDP数据报:
byte[ ] buffer = new byte[8912];
DatagramPacket datap = new DatagramPacket(buffer ,buffer.length( ));
在UDP报文中,数据报长度用2个字节的无符号整数表示,所以理论上UDP报文的最大长度为65536字节(包含UDP头部以及IP头部)。但是实际上,大多数系统限制了数据报的长度为8192字节。在具体的网络环境中,这个限制值可能更小。9.3 UDP实例程序29.3 UDP实例程序2
9.3.2 服务器程序
创建发送数据报的构造方法是:
public DatagramPacket(byte[] buf, int length, InetAddress address, int port)
public DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
其中,缓冲区buf为发送数据存储区。address和port指定目标主机的IP地址和端口号。9.3 UDP实例程序29.3 UDP实例程序2
9.3.2 服务器程序
例如,下面的程序段创建了一个名为outgoing的发送数据报:
try {
InetAddress server = InetAddress.getByName("192.168.34.12");
int port = 3737;
byte[] data = "This is a test".getBytes();
DatagramPacket outgoing = new DatagramPacket(data, data.length, server, port);
...
}catch(IOException e){
...
}9.3 UDP实例程序29.3 UDP实例程序2
9.3.2 服务器程序
DatagramPacket类中定义了一些用来对数据报进行设置或者从中提取信息的方法,下面是几个常用的方法:
public InetAddress getAddress():返回一个IP地址,如果是发送数据报则指目标主机,如果是接收数据报指则源主机。
public void setAddress(InetAddress remote):设置目标主机的IP地址。
public int getPort():返回一个端口号,发送数据报指目标主机的端口号,接收数据报指来自源主机的端口号。
public void setPort(int iport):设置端口号。
public byte[] getData():获得数据报的数据缓冲区,不论是发送数据报还是接收数据报,数据存储从offset位置开始。9.3 UDP实例程序29.3 UDP实例程序2
9.3.2 服务器程序
public int getOffset():获得发送数据或者接收数据在数据缓冲区中的偏移量(offset)。
public int getLength():获得发送数据或者接收数据的长度。
public void setData(byte[] buf, int offset, int length):设置数据缓冲区、偏移量和长度。还可以使用方法setData(byte[] buf)和setLength(int length)单独设置缓冲区和长度。