《移动编程技术第七讲.ppt》由会员分享,可在线阅读,更多相关《移动编程技术第七讲.ppt(23页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、移动编程技术移动编程技术(七)(七)哈尔滨工程大学软件学院目 录 UDP协议概述 UDP协议的应用 基于UDP的DatagramSocket 基于UDP的DatagramPacket TCP与UDP对比 Android蓝牙通信UDP协议TCP协议面向连接的可靠性是有代价的,这种代价就是传输速度的降低。由于建立和销毁连接会话费较长的时间,如果通信双方实际上要传输的数据很小,那么建立和销毁TCP连接的代价就相对较高。UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是无连接的协议,即在正式通信前不必与对方事先建立连接,不必知晓对方状态就直接向对方发送数据。正由
2、于UDP无连接的特点,使其比TCP具有更快的传输速度,但可靠性却无法保证。UDP发送的数据单元为UDP数据报(简称报文),协议无法保证传输中的报文一定到达目的地,也无法保证各个报文按发送的顺序到达目的地。UDP协议的特性(1)UDP是一个无连接协议,传输数据之前发送端和接收端不建立连接,当需要发送数据时就直接去获取来自应用程序的数据,并以一个个数据报的形式尽可能快的把数据发送到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个数据报放在队列中,应用程序每次从队列中读一个数据报。(2)由于传输数据不建立连接,因此也就不需要维
3、护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。(3)UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。(4)UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表。(5)UDP是面向报文的。发送端每次发送一个报文,接收时,每次读取一个报文,报文和报文是不会合并的,如果接收端的缓冲区小于报文长度,则多出的部分会被丢弃。因此,应用程序需要选择合适的报文大小。UDP协议的应用既然UDP是一种不可靠的网络协议,那么还有什么使用价值或必要呢?实际上,在某些情况下UDP协议非常有用。因为UDP具有TCP协议所难以达到的
4、速度优势。虽然TCP协议中定义了各种可靠保障机制,但是在实际执行的过程中会占用大量的系统开销,无疑使速度受到严重的影响。而UDP协议由于去除了信息可靠传递机制,将确认和排序等功能移交给上层应用来完成,极大降低了数据收发的时间,使速度得到了保证。目前,包括视频电话会议系统、即时通信系统(如QQ)在内的许多应用都证明了UDP协议的存在价值。因为相对于可靠性来说,这些应用更加注重实际性能,所以为了获得更好的使用效果(如更高的画面帧刷新速率,更快的消息送达)往往可以牺牲一定的可靠性。TCP协议与UDP协议的区别TCP协议与UDP协议的区别TCP协议与UDP协议的选择 当数据传输的性能必须让位于数据传输
5、的完整性、可控制性和可靠 性时,TCP协议是当然的选择。当强调传输性能而不是传输的完整性时,UDP是最好的选择。在数据传输时间很短,以至于此前的连接过程成为整个流量主体的 情况下,UDP也是一个好的选择(如DNS交换)。这就是UDP和TCP两种协议的权衡之处,要根据不同的环境和特点,使得两种传输协议在网络通信中发挥各自重要的作用。DatagramSocket在Java中,DatagramSocket类负责接收和发送UDP数据报,每一个DatagramSocket与一个本地地址(包括本地主机的IP地址和本地UDP端口)绑定,在此端口监听发送过来的数据报。在客户端程序中,一般由操作系统为Datag
6、ramSocket分配本地端口,这种端口也称为匿名端口;在服务器程序中,一般有程序显示的为DatagramSocket指定本地端口。(UDP与TCP可以共用同一端口)每个DatagramSocket可以把UDP数据报发送给任意一个远程的DatagramSocket,也可以接收来自任意一个远程DatagramSocket的UDP数据报。由于UDP协议无连接的特性,客户端的DatagramSocket与服务器端的DatagramSocket不存在一一对应关系,两者无需建立连接,就能交换数据报。DatagramSocketDatagramSocket类的构造方法:DatagramSocket()Da
7、tagramSocket(int port)DatagramSocket(int port,InetAddress addr)DatagramSocket(SocketAddress saddr)第一个不带参数的构造方法使DatagramSocket对象与匿名端口绑定(由操作系统分配可用端口)其余方法需要显示的指定本地端口构造方法三、四用于一个主机有多个IP地址的场合,明确指定DatagramSocket对象所绑定的IP地址DatagramSocket接收和发送数据报:send(DatagramPacket dp)receive(DatagramPacket dp)send()方法用于发送一个
8、数据报,由于UDP提供不可靠传输,如果数据报没有到达目的地,send()方法也不会抛出任何异常,因此发送方无法知道数据报是否被对方接收,除非通过应用层协议通知重发。如果发送的数据报超过了底层网络所支持的数据报大小,可能会抛出SocketException:The message islarger than the maximum supported by underlying transport.receive()方法用于接收一个数据报,如果网络上没有数据报,执行该方法的线程会进程阻塞状态,直到收到数据报为止。DatagramSocket连接管理:void connect(InetAddres
9、s host,int port)void disconnect()int getPort()InetAddress getInetAddress();SocketAddress getRemoteSocketAddress()如果一个DatagramSocket只希望与一个固定的远程DatagramSocket通信,可以使用connect()方法建立“连接”。connect()方法实际上不建立TCP意义上的连接,但它能限制当前DatagramSocket只向该远程DatagramSocket发送数据报,如果当前DatagramSocket试图向其它主机或UDP端口发送数据报,当执行send()
10、方法时会抛出IllegalArgumentException,来自指定的远程DatagramSocket以外的主机或UDP端口的数据报将全部被丢弃,程序不会得到任何通知,也不会抛出任何异常。DatagramSocket连接管理:void connect(InetAddress host,int port)void disconnect()int getPort()InetAddress getInetAddress();SocketAddress getRemoteSocketAddress()当调用disconnect()方法后,则解除前述“连接关系”,DatagramSocket就可以再次
11、对其它任何主机和UDP端口收发数据报。仅当DatagramSocket已经建立“连接”时,后三个方法才有效,可以返回远程主机的端口、IP地址。通常情况下,UDP客户端程序可以与指定的UDP服务器通信,可以将客户端DatagramSocket通过connect方法建立“连接”。UDP服务器需要与多个客户端程序通信,一般不用建立特定的“连接”。DatagramPacketDatagramPacket类表示数据报,它的构造方法分为两类:一类用于接收数据,一类用于发送数据。其主要区别是,用于发送数据的构造方法需要设定数据报的目的地址,用于接收数据的构造方法则无须设定地址。用于接收数据的构造方法:Dat
12、agramPacket(byte data,int length)DatagramPacket(byte data,int offset,int length)接收数据报代码:DatagramSocket so=new DatagramSocket();byte data=new byte512;DatagramPacket dp=new DatagramPacket(data,512);so.receive(dp);DatagramPacketDatagramPacket类的构造方法:用于发送数据的构造方法:DatagramPacket(byte data,int length,InetAd
13、dress addr,int port)DatagramPacket(byte data,int length,SocketAddress saddr)DatagramPacket(byte data,int offset,int length,InetAddress addr,int port)DatagramPacket(byte data,int offset,int length,SocketAddress saddrt)发送数据报代码:DatagramSocket so=new DatagramSocket();byte data=你好.getByte();SocketAddress
14、 ra=new InetSocketAddress(192.168.1.9,9999)DatagramPacket dp=new DatagramPacket(data,data.length,ra);so.send(dp);选择数据报的大小一个完整的UDP数据报包括IP首部,UDP首部和数据这三部分。UDP首部主要包括源端口与目标端口。我们说的数据报长度或大小,实际上指的是数据报中数据部分的长度或大小。由于不同网络层面及不同协议允许传输的最大数据单元MTU的限制,Internet中,标准MTU值为576字节,UDP的数据最大长度最好为548字节(去掉IP首部20字节,UDP首部8字节)在局域
15、网中,由于数据帧的长度必须在46-1500字节之间,因此数据最大长度最好为1472字节(去掉IP首部20字节,UDP首部8字节)否则,网络可能会将数据报截断、分片、或者丢弃。数据格式的转换由于数据报中只能存放字节形式的数据,在发送方,需要把其他格式的数据转换为字节数组,在接收方,需要把字节数组转换为原来格式的数据。可以借助DataOutputStream及DataInputStream完成数据读写时的格式转换。long型数组转换为byte数组 public byte longToByte(long data)throws IOException ByteArrayOutputStream ou
16、t=new ByteArrayOutputStream();DataOutputStream dos=new DataOutputStream(out);for(int i=0;idata.length;i+)dos.writeLong(datai);dos.close();return out.toByteArray();数据格式的转换 byte数组还原为long型数组 public long byteToLong(byte data)throws IOException/一个long型占据8字节 long result=new longdata.length/8;ByteArrayInpu
17、tStream input=new ByteArrayInputStream(data);DataInputStream dis=new DataInputStream(input);for(int i=0;idata.length/8;i+)resulti=dis.readLong();return result;Android蓝牙通信四个重要的类:BluetoothAdapterBluetoothDeviceBluetoothServerSocketBluetoothSocket 两个权限:Android蓝牙通信蓝牙通信基本步骤:1、获取本地蓝牙适配器 BluetoothAdapter m
18、Adapter=BluetoothAdapter.getDefaultAdapter();2、打开蓝牙 if(!mAdapter.isEnabled()/弹出对话框提示用户是后打开Intent enabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enabler,REQUEST_ENABLE);/不做提示,强行打开 /mAdapter.enable();Android蓝牙通信蓝牙通信基本步骤:3、搜索设备定义BroadcastReceiver并执行mAdapter.startDisco
19、very()BroadcastReceiver mReceiver=new BroadcastReceiver()public void onReceive(Context context,Intent intent)String action=intent.getAction();if(BluetoothDevice.ACTION_FOUND.equals(action)/找到设备 BluetoothDevice device=intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);if(device.getBondState()!=
20、BluetoothDevice.BOND_BONDED)Log.e(TAG,find device:+device.getName()+device.getAddress();else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)if(mNewDevicesAdapter.getCount()=0)Log.v(TAG,搜索完成);Android蓝牙通信蓝牙通信基本步骤:4、建立Socket连接(UUID需要相同)服务器端:BluetoothServerSocket serverSocket=mAdapter.liste
21、nUsingRfcommWithServiceRecord(serverSocketName,UUID);serverSocket.accept();客户端:BluetoothSocket clienSocket=dcvice .createRfcommSocketToServiceRecord(UUID);clienSocket.connect();5、获取输入输出流InputStream inputStream=socket.getInputStream();OutputStream=socket.getOutputStream();上机练习1)练习创建客户端Socket,可以通过扫描远程
22、主机的端口进行练习2)练习通过Socket收发Http请求。提示,HTTP首部可通过firefox、chrome等网络分析工具获取sb.append(Host:rn);sb.append(Accept:*/*rn);sb.append(User-Agent:Mozilla/5.0(Windows NT 6.1;WOW64)AppleWebKit/537.31(KHTML,like Gecko)Chrome/26.0.1410.64 Safari/537.31rn);3)创建服务器端ServerSocket,与Android端Socket进行对话4)分别创建服务器端与客户端DatagramSocket,练习UDP协议的服务器与客户端通信