网络编程之 udp
计算机网络,就是把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息,共享硬件、软件、数据信息等资源。
网络体系结构:国际标准化组织 ISO 于 l978 年提出“开放系统互连参考模型”,即著名的 OSI ( OpenSystemInterconnection )模型。该模型把计算机网络分成物理层、数据链路层、网络层、传输层、会话层、表示层、应用层等七层。
通信协议
计算机网络中实现通信必须有一些约定,即通信协议。对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准。
TCP 协议:提供可靠的数据传输服务的规则。
IP 协议进行 IP 数据包的分割和组装。
但是通过 IP 协议并不能清楚地了解到数据包是否顺利地发送给目标计算机。而使用 TCP 协议,它将数据包成功发送给目标计算机后,会要求发送一个确认,如果在某个时间内没有收到确认, TCP 将重新发送数据包。
首先了解一下神马是 UDP 协议 ;
UDP(UserDatagramProtocol) 协议是用户数据报,在网络中它与 TCP 协议一样用于处理数据包。在 OSI 模型中,在第四层——传输层,处于 IP 协议的上一层。
UDP 是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
为什么要使用 UDP ?
在网络质量令人不十分满意的环境下, UDP 协议数据包丢失会比较严重。但是由于 UDP 的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用 UDP 较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如聊天用的 ICQ 和 OICQ 就是使用的 UDP 协议。
上网搜索摸个网站的时候,本机是先访问本地的 hosts 文件区,去找该主机名是否有对应的 ip 地址;
C:\Windows\System32\drivers\etc\hosts; 在里面可以加上你经常进的网站和 ip ;
InetAddress :用于描述 IP 地址的对象
InetAddress
类没有提供构造方法,而是提供了两个静态方法来获取
InetAddress
实例
getByName(Stringhost)
:根据主机获取对应的
InetAddress
对象。
getByAddress(byte[]addr)
:根据原始
IP
地址来获取对应的
InetAddress
对象。
// 将指定 ip 封装成 InetAddress 对象。
InetAddressia=InetAddress.getByName("127.0.0.1");
在
Java
中操纵
UDP
使用位于
JDK
中
Java.net
包下的
DatagramSocket
和
DatagramPacket
类,可以非常方便地控制用户数据报文。
每个数据包的大小限制在 64k 内;
面向无连接,是不可靠协议,容易丢包;
不需要连接,速度快;
DatagramSocket 类:创建接收和发送 UDP 的 Socket 实例
DatagramSocket() :创建实例。通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。
DatagramSocket(intport) :创建实例,并固定监听 Port 端口的报文。
DatagramSocket(intport,InetAddresslocalAddr) :这是个非常有用的构建器,当一台机器拥有多于一个 IP 地址的时候,由它创建的实例仅仅接收来自 LocalAddr 的报文。
receive(DatagramPacketd) :接收数据报文到 d 中。 receive 方法产生一个“阻塞”。
send(DatagramPacketd) :发送报文 d 到目的地。
setSoTimeout(inttimeout) :设置超时时间,单位为毫秒。
close()
:关闭
DatagramSocket
。在应用程序退出的时候,通常会主动释放资源,关闭
Socket
,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭
Socket
,或在捕获到异常抛出后关闭
Socket
。
建立一个 upd 的发送端。
用于发送数据。
1, 建立 updsocket 服务。
2 ,将数据封装成数据包。
3 ,通过 socket 服务的 send 方法。将数据包发出。
4 ,关闭资源。
*/
//1, 建立 udpsocket 服务。
DatagramSocketds=newDatagramSocket;
//2, 将数据封装成数据包。要使用 DatagramPacket 对象
//2.1 先将要发送的数据变成字节数组。在指定发送的目的地和端口。
//2.2 将这些信息作为参数传递给数据包对象的构造函数。
byte[]bf=”hahah,wolaile”.getBytes[];
InetAdressip=InetAdress.getName(“192.168.49.111”);
DatagramPacketdp=newDatagramPacket(bf,bf.getLength,ip,9909);
//3, 使用 Socket 服务的 send 方法将数据包发送出去。
Ds.send(dp);
//4, 关闭资源。
ds.close;
/*
建立 udp 的接收端。
1 ,建立 udp 接收端服务,必须要监听一个端口,因为要明确,哪个端口来的数据是由该应用程序所处理的。
2 ,建立一个空的数据包,用于存储接收到数据,
将字节数据存储到数据包对象中,可以使用数据包对象的方法获取不同的数据信息。
3 ,使用 Socket 服务的 receive 方法将接收到的数据存储到数据包中。
4 ,通过数据包的方法获取指定数据信息。
5 ,关闭资源。
*/
//1, 建立 updsocket 服务,监听一个端口。
DatagramSocketds=newDatagramSocket(9909);
//2, 建立一个执行大小的数据包,用于存储数据,以便获取。
byte[]bf=newbyte[1024];
DatagramPacketdp=newDatagramPacket(bf,bf.getLength);
//3, 使用 socket 的 receive 方法将数据存储到数据包中。
ds.receive();
//4, 通过数据包对象的方法获取其中的数据。
Stringip=getAddress().getHostAdress();
Stringdata=newString(dp.getData(),0,dp.getLength);
intport=dp.getPort();
System.out.println(ip+”:”+data+”::”+port);
//5, 关闭资源。
ds.close();
package com.csdn.hbsi; /* 需求: 制作一个dos版的聊天程序。 1,对于聊天分两个动作,接收和发送。 2,接收和发送都需要同时运行。这就使用到了多线程技术。 一个线程控制接收,一个线程控制发送。 3,既然要进行群聊。那么就要使用socket网络服务。这里我们使用Udp完成。 */ import java.net.*; import java.io.*; class ChatSend implements Runnable { private DatagramSocket ds; ChatSend(DatagramSocket ds) { this.ds = ds; } public void run() { BufferedReader bufr = null; try { bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((line=bufr.readLine())!=null) { if("886".equals(line)) break; byte[] buf = line.getBytes(); DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.49.255"),9008); ds.send(dp); } ds.close(); }catch (Exception e) { System.out.println(e.toString()); } } } class ChatRece implements Runnable { private DatagramSocket ds; ChatRece(DatagramSocket ds){ this.ds = ds;<!--EndFragment--> } public void run(){ while(true){ try{ byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); ds.receive(dp); String ip = dp.getAddress().getHostAddress(); String data = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+"::"+data); }catch (Exception e){ System.out.println(e.toString()); } } } } class ChatDemo { public static void main(String[] args) throws Exception{ DatagramSocket send = new DatagramSocket(); DatagramSocket rece = new DatagramSocket(9008); new Thread(new ChatSend(send)).start(); new Thread(new ChatRece(rece)).start(); } }