当前的网络中有三种通讯模式:单播、广播、组播(多播),其中的组播出现时间最晚但同时具备单播和广播的优点,最具有发展前景。
一、单播:
主机之间“一对一”的通讯模式,网络中的交换机和路由器对数据只进行转发不进行复制。如果10个客户机需要相同的数据,则服务器需要逐一传送,重复10次相同的工作。但由于其能够针对每个客户的及时响应,所以现在的网页浏览全部都是采用IP单播协议。网络中的路由器和交换机根据其目标地址选择传输路径,将IP单播数据传送到其指定的目的地。
单播的优点:
1. 服务器及时响应客户机的请求
2. 服务器针对每个客户不通的请求发送不通的数据,容易实现个性化服务。
单播的缺点:
1. 服务器针对每个客户机发送数据流,服务器流量=客户机数量×客户机流量;在客户数量大、每个客户机流量大的流媒体应用中服务器不堪重负。
2. 现有的网络带宽是金字塔结构,城际省际主干带宽仅仅相当于其所有用户带宽之和的5%。如果全部使用单播协议,将造成网络主干不堪重负。现在的P2P应用就已经使主干经常阻塞,只要有5%的客户在全速使用网络,其他人就不要玩了。而将主干扩展20倍几乎是不可能。
二、 广播:
主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无条件复制并转发,所有主机都可以接收到所有信息(不管你是否需要),由于其不用路径选择,所以其网络成本可以很低廉。有线电视网就是典型的广播型网络,我们的电视机实际上是接受到所有频道的信号,但只将一个频道的信号还原成画面。在数据网络中也允许广播的存在,但其被限制在二层交换机的局域网范围内,禁止广播数据穿过路由器,防止广播数据影响大面积的主机。
广播的优点:
1. 网络设备简单,维护简单,布网成本低廉
2. 由于服务器不用向每个客户机单独发送数据,所以服务器流量负载极低。
广播的缺点:
1.无法针对每个客户的要求和时间及时提供个性化服务。
2. 网络允许服务器提供数据的带宽有限,客户端的最大带宽=服务总带宽。例如有线电视的客户端的线路支持100个频道(如果采用数字压缩技术,理论上可以提供500个频道),即使服务商有更大的财力配置更多的发送设备、改成光纤主干,也无法超过此极限。也就是说无法向众多客户提供更多样化、更加个性化的服务。
3. 广播禁止在Internet宽带网上传输。
三、组播:
主机之间“一对一组”的通讯模式,也就是加入了同一个组的主机可以接受到此组内的所有数据,网络中的交换机和路由器只向有需求者复制并转发其所需数据。主机可以向路由器请求加入或退出某个组,网络中的路由器和交换机有选择的复制并传输数据,即只将组内数据传输给那些加入组的主机。这样既能一次将数据传输给多个有需要(加入组)的主机,又能保证不影响其他不需要(未加入组)的主机的其他通讯。
组播的优点:
1. 需要相同数据流的客户端加入相同的组共享一条数据流,节省了服务器的负载。具备广播所具备的优点。
2. 由于组播协议是根据接受者的需要对数据流进行复制转发,所以服务端的服务总带宽不受客户接入端带宽的限制。IP协议允许有2亿6千多万个(268435456)组播,所以其提供的服务可以非常丰富。
3. 此协议和单播协议一样允许在Internet宽带网上传输。
组播的缺点:
1.与单播协议相比没有纠错机制,发生丢包错包后难以弥补,但可以通过一定的容错机制和QOS加以弥补。
(2)客户端
2、单播(DatagramSocket)
(2)端2:
3、广播(没有客户端和服务端之分)
(2)端2:
一、单播:
主机之间“一对一”的通讯模式,网络中的交换机和路由器对数据只进行转发不进行复制。如果10个客户机需要相同的数据,则服务器需要逐一传送,重复10次相同的工作。但由于其能够针对每个客户的及时响应,所以现在的网页浏览全部都是采用IP单播协议。网络中的路由器和交换机根据其目标地址选择传输路径,将IP单播数据传送到其指定的目的地。
单播的优点:
1. 服务器及时响应客户机的请求
2. 服务器针对每个客户不通的请求发送不通的数据,容易实现个性化服务。
单播的缺点:
1. 服务器针对每个客户机发送数据流,服务器流量=客户机数量×客户机流量;在客户数量大、每个客户机流量大的流媒体应用中服务器不堪重负。
2. 现有的网络带宽是金字塔结构,城际省际主干带宽仅仅相当于其所有用户带宽之和的5%。如果全部使用单播协议,将造成网络主干不堪重负。现在的P2P应用就已经使主干经常阻塞,只要有5%的客户在全速使用网络,其他人就不要玩了。而将主干扩展20倍几乎是不可能。
二、 广播:
主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无条件复制并转发,所有主机都可以接收到所有信息(不管你是否需要),由于其不用路径选择,所以其网络成本可以很低廉。有线电视网就是典型的广播型网络,我们的电视机实际上是接受到所有频道的信号,但只将一个频道的信号还原成画面。在数据网络中也允许广播的存在,但其被限制在二层交换机的局域网范围内,禁止广播数据穿过路由器,防止广播数据影响大面积的主机。
广播的优点:
1. 网络设备简单,维护简单,布网成本低廉
2. 由于服务器不用向每个客户机单独发送数据,所以服务器流量负载极低。
广播的缺点:
1.无法针对每个客户的要求和时间及时提供个性化服务。
2. 网络允许服务器提供数据的带宽有限,客户端的最大带宽=服务总带宽。例如有线电视的客户端的线路支持100个频道(如果采用数字压缩技术,理论上可以提供500个频道),即使服务商有更大的财力配置更多的发送设备、改成光纤主干,也无法超过此极限。也就是说无法向众多客户提供更多样化、更加个性化的服务。
3. 广播禁止在Internet宽带网上传输。
三、组播:
主机之间“一对一组”的通讯模式,也就是加入了同一个组的主机可以接受到此组内的所有数据,网络中的交换机和路由器只向有需求者复制并转发其所需数据。主机可以向路由器请求加入或退出某个组,网络中的路由器和交换机有选择的复制并传输数据,即只将组内数据传输给那些加入组的主机。这样既能一次将数据传输给多个有需要(加入组)的主机,又能保证不影响其他不需要(未加入组)的主机的其他通讯。
组播的优点:
1. 需要相同数据流的客户端加入相同的组共享一条数据流,节省了服务器的负载。具备广播所具备的优点。
2. 由于组播协议是根据接受者的需要对数据流进行复制转发,所以服务端的服务总带宽不受客户接入端带宽的限制。IP协议允许有2亿6千多万个(268435456)组播,所以其提供的服务可以非常丰富。
3. 此协议和单播协议一样允许在Internet宽带网上传输。
组播的缺点:
1.与单播协议相比没有纠错机制,发生丢包错包后难以弥补,但可以通过一定的容错机制和QOS加以弥补。
2.现行网络虽然都支持组播的传输,但在客户认证、QOS等方面还需要完善,这些缺点在理论上都有成熟的解决方案,只是需要逐步推广应用到现存网络当中。
实现:
1、单播(ServerSocket)
(1)服务端
public class TcpServer {
ServerSocket serverSocket;
Socket socket;
InetAddress address;
public void init() {
try {
address=InetAddress.getByName("128.0.0.0");
serverSocket = new ServerSocket(5656,10,address);
while (true) {
System.out.println("waiting...");
socket = serverSocket.accept();
new MyThread(socket).start();
System.out.println("one start");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class MyThread extends Thread {
Socket socket;
public MyThread(Socket socket) {
// TODO Auto-generated constructor stub
this.socket = socket;
}
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
OutputStream outputStream = socket.getOutputStream();
outputStream.write(("rou wo wo " + Thread.currentThread()
.getName()).getBytes());
try {
sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new TcpServer().init();
}
}
(2)客户端
public class TcpClient {
Socket socket;
public void init() {
try {
socket = new Socket("192.0.0.1", 5656);
while (true) {
InputStream inputStream = socket.getInputStream();
int i = 0;
byte bs[] = new byte[1024];
while ((i = inputStream.read(bs)) > 0) {
System.out.println(new String(bs));
}
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new TcpClient().init();
}
}
2、单播(DatagramSocket)
(1)端1
public class UdpServer {
DatagramSocket datagramSocket;
int port = 7070;
DatagramPacket outPacket;
byte[] bs = new byte[1024];
String ip = "172.22.67.6";
int i = 0;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new UdpServer().init();
}
public void init() {
try {
datagramSocket = new DatagramSocket(8002);
try {
outPacket = new DatagramPacket(bs, bs.length,
InetAddress.getByName("127.0.0.1"), 8003);
while (true) {
outPacket
.setData(("jia you nuan wo zi" + (++i)).getBytes());
datagramSocket.send(outPacket);
System.out.println("send ~" + i);
Thread.sleep(2000);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
(2)端2:
public class UdpClient {
DatagramSocket datagramSocket;
int port = 7070;
DatagramPacket inPacket;
byte[] bs = new byte[1024];
String ip = "172.22.67.6";
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new UdpClient().init();
}
public void init() {
try {
datagramSocket =new DatagramSocket(8003,
InetAddress.getByName("127.0.0.1"));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
inPacket = new DatagramPacket(bs, bs.length);
while (true) {
datagramSocket.receive(inPacket);
System.out.println("udp receive " + new String(bs));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3、广播(没有客户端和服务端之分)
(1)端1:
public class MulUdpClient {
String ip = "230.0.0.0";
MulticastSocket datagramSocket;
int port = 5050;
DatagramPacket inPacket;
byte[] receive = new byte[1025];
InetAddress address;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new MulUdpClient().init();
}
public void init() {
try {
datagramSocket = new MulticastSocket(port);
address = InetAddress.getByName(ip);
datagramSocket.joinGroup(address);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
inPacket = new DatagramPacket(receive, receive.length);
while (true) {
try {
System.out.println("wait for server");
datagramSocket.receive(inPacket);
System.out.println("receive " + new String(receive));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
(2)端2:
public class MulUdpServer {
MulticastSocket multicastSocket;
String ip = "230.0.0.0";
int port = 5050;
InetAddress socketAddress;
DatagramPacket datagramPacket;
int i = 0;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new MulUdpServer().initServer();
}
public void initServer() {
try {
multicastSocket = new MulticastSocket(port);
socketAddress = InetAddress.getByName(ip);
multicastSocket.joinGroup(socketAddress);
multicastSocket.setLoopbackMode(false);
datagramPacket = new DatagramPacket(new byte[0], 0, socketAddress,
port);
new Thread() {
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
try {
datagramPacket
.setData(("wo ai ni dudu " + (++i))
.getBytes());
multicastSocket.send(datagramPacket);
System.out.println("send success!" + i);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}