最近在看《Java网络编程》,对于0基础的我来说,真是受益匪浅,从中学到了很多,使我对自己平时常用的网络操作等也有了进一步的了解。强烈建议同学们去看看这本书。
一:Socket
【基本概念】
网络套接字,是真正直接操作的东西,是基于TCP封装的Api。这也是Socket与http,Tcp,udp,ip等协议最本质的区别。
注:在Unix系统中,Socket是操作系统的套接字。
【基本用法】
都知道它被翻译为”套接字”,其使用方法如下:
String host = "localhost";
int port = 8080;
try{
Socket socket = new Socket(host,port);
//这里实例化一个Socket对象时,它会利用InetAddress对像去进行一个connet(),所以外面不用再去
//掉用链接操作,只要从这个指定的端口上读取数据就ok了。
}catch(Exception e){
}
如上,客户端进行Socket通信很简单,只要根据指定的主机名,端口号,创建Socket对象就好了,
就只等服务端ServerSokcet在指定端口号上监听到返回数据了,因此Socket通信是建立在已连接上的。
【优缺点】
优点:实时性强,
【应用场景】
CS模式如即时通信、浏览器对Server服务器
二:Http协议
【基本概念】
这就是超文本传输协议,是基于TCP/IP的协议,属于应用层协议(应用层协议的比如:HTTP,FTP,SMTP,TELNET等),
而要使用Http协议,我们最常用到的就是URLConnection,HttpURLConnection
URL url = new URL("http://www.baidu.com?test=1");
URLConnection conn = url.openConnection();
//下面就是用输入/输出流读写数据
//最后对流进行关闭,对连接进行关闭
Http通信过程可概括为:
建立连接—-> Client向服务器发送请求 ——> Server返回数据
【优缺点】
优点:应用级接口,使用方便
缺点:数据为明文传输,缺少安全性
【使用场景】
应用程序网络请求。
总结:
Socket与URLConnection一样,是使用其里面的协议进行网络通信;
Socket是基于TCP/IP协议栈的封装,是直接操作的东西;
URLConnection是使用HTTP协议,
三:UDP协议
【基本概念】
在OSI七层模型中,UDP与TCP同属传输层协议,其中TCP是面向连接的,而UDP是不面向连接的。UDP的传输方式有三种:广播、单播、多播、任播。基中广播是针对子网中的特殊地址,即广播地址:255.255.255.255,将消息发送给同一广播网络中的所有主机。
单播:是指封包在计算机网络的传输中,目的地址为单一目标的一种传输方式。它是现今网络应用最为广泛,通常所使用的网络协议或服务大多采用单播传输,例如一切基于TCP的协议。
多播:多点广播或群播。也称组播,是指把信息同时传递给一组目的地址。它使用策略是最高效的,因为消息在每条网络链路上只需传递一次,而且只有在链路分叉的时候,消息才会被复制。
多播组通过 D 类 IP 地址和标准 UDP 端口号指定。D 类 IP 地址在 224.0.0.0 和 239.255.255.255 的范围内(包括两者)。地址 224.0.0.0 被保留,不应使用。
任播:是一种网络寻址和路由的策略,使得消息可以根据路由拓朴来决定送到“最近”或“最好”的目的地。
【基本用法】
单播 与 广播 都使用 DatagramSocket类,多播使用 DatagramSocket的子类:MulticastSocket。
第一步:实例化
private DatagramSocket socket = null;
private DatagramPacket recvPacket = null;
private int port = 5555;
//广播地址
private final static String BROADCAST_ADD = "255.255.255.255";
//多播ip
private static String MULTICAST_ADDRESS = "225.0.0.1";
private byte[] recvBuffer = new byte[1024];
protected void init(){
//DatagramSocket类实例化
try {
socket = new DatagramSocket(port, InetAddress.getLoopbackAddress());
} catch (SocketException e) {
e.printStackTrace();
}
//多播MulticastSocket实例化
try {
socket = new MulticastSocket(port);
((MulticastSocket) socket).joinGroup(InetAddress.getByName(MULTICAST_ADDRESS));
}catch (IOException e) {
e.printStackTrace();
}
recvPacket = new DatagramPacket(recvBuffer, recvBuffer.length);
}
第二步:发送消息
public boolean send(InetAddress addr, int port, String msg) {
byte[] buffer = msg.getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
System.out.println("send to " + addr.getHostAddress());
try {
//单播
// packet.setAddress(addr);
//多播
//packet.setAddress(InetAddress.getByName(MULTICAST_ADDRESS));
//广播
packet.setAddress(InetAddress.getByName(BROADCAST_ADD));
packet.setPort(port);
socket.send(packet);
return true;
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
第三步:接收消息
public void receive(){
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
socket.receive(recvPacket);
System.out.println("received packet from " +
recvPacket.getAddress().getHostAddress() + " : " + recvPacket.getPort());
//注意由于DatagramPacket的缓冲区复用,本次收到的最后一个字符后并不会补'\0',而是使用一个长度标记
String msg = new String(recvPacket.getData(), recvPacket.getOffset(), recvPacket.getLength());
System.out.println("received " + msg);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
socket.close();
}
}
}
}).start();
}
【优缺点】
优点:面向非连接,传输速度快。
缺点:传输不可靠,只能用于传输少量数据。
【使用场景】
现在智能家居设备通信大都使用UDP协议。