您的位置:首页 > 理论基础 > 计算机网络

网络编程学习笔记(二)UDP协议及聊天小程序的实现

2017-05-24 10:31 931 查看
UDP协议是传输层协议,它是无连接,不保证可靠的传输层协议。那么如果要进行发送端和接收端的通讯应该如何进行?

两个基本概念:

1.Socket 套接字

Socket就是为网络服务提供的一种机制

网络通信其实就是Socket间的通信

(网络想要进行通信需要两个端点)数据在两个Socket间通过IO传输

2.UDP传输(Java中建立了一些对象对UDP进行封装,方便我们进行操作)

DatagramSocket 此类用来发送和接收数据报包的套接字

DatagramPacket 此类表示数据报包,数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证,因此是不可靠的。(构造参数中带有地址信息的DatagramPacket对象是用来发送数据报包的)

UDP协议-发送端

创建UDP传输的发送端

(1)建立UDP的Socket服务

(2)将要发送的数据封装到数据包中

(3)通过UDP的Socket服务将数据包发送出去

(4)关闭Socket服务

public class UDPSendDemo {
public static void main(String[] args) throws IOException {
System.out.println("发送端启动");
//1.udpsocket服务,使用DatagramSocket对象
DatagramSocket ds = new DatagramSocket();
//2.将要发送的数据装到数据包中
String str = "udp传输演示";
//使用DatagramPacket将数据封装到该对象包中
byte[] buf = str.getBytes();
/*
构造方法:
DatagramPocket(byte[] buf,int length,InetAddress address,int port):
构造数据包,用来将长度为length的包发送到指定主机上的指定端口号。
端口号在0-65535之间即可,尽量避免0-1024,避免与系统冲突
*/
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),10000);//10000为目的端口号
//3.通过UDP的Socket服务,将数据包发送出去
ds.send(dp);
ds.close();
}
}


UDP协议-接收端

建立UDP接收端的思路

(1)建立UDP Socket服务,因为要接收数据,必须要明确一个端口号

(2)创建数据包,用于存储接收到的数据,方便用数据包对象的方法解析这些数据

(3)使用Socket服务的receive方法,将接收到的数据存储到数据包中

(4)通过数据包的方法解析数据包中的数据

(5)关闭资源

public class UDPReceDemo {

public static void main(String[] args) throws IOException {
System.out.println("接收端启动");
//1.建立UDP Socket服务
//构造数据报套接字并将其绑定到本地主机上任何可用的端口。套接字将被绑定到通配符地址,IP地址由内核来选择
DatagramSocket ds = new DatagramSocket(10000);
//2.创建数据包
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//3.使用接收方法将数据存储到数据包中
ds.receive(dp);//阻塞式的
//4.通过数据包对象的方法,解析其中的数据,比如地址,端口,数据内容
String ip = dp.getAddress().getHostAddress();//dp.getAddress()是获取IP地址对象
int port = dp.getPort();//注意,此处的端口指的不是本地端口,而是指发送源的端口,即由谁发送来的
String text = new String(dp.getData(),0,dp.getLength());//用于存储的buf数组是1024大小,但是实际可能很小,因此将其有效位变为字符串返回
System.out.println(ip+":"+port+":"+text);
//5.关闭资源
ds.close();
}

}


运行结果





注意:62086指的是源端口号,即由哪个端口发送过来的

聊天小程序

为了使聊天内容在同一窗口显示,我们在这里使用多线程技术,让接收和发送分别在不同线程进行运行:



发送端

为了达到键盘输入的目的,我们这里使用BufferedReader,通过设置特殊字符串来判断是否截止,例如这里使用的“over”

public class Send implements Runnable {
private DatagramSocket ds;
public Send(DatagramSocket ds){
this.ds = ds;
}
@Override
public void run(){
try{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line=bufr.readLine())!=null) {
//使用DatagramPacket将数据封装到该对象包中
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 10001);
ds.send(dp);
if ("over".equals(line))
break;//注意此时over已经发送出去
}
ds.close();
}catch(Exception e){

}
}
}


接收端

public class Rece implements Runnable{
private DatagramSocket ds;
public Rece(DatagramSocket ds){
this.ds = ds;
}
@Override
public void run(){
try{
while (true){
//2.创建数据包
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//3.使用接收方法将数据存储到数据包中
ds.receive(dp);//阻塞式的
//4.通过数据包对象的方法,解析其中的数据,比如地址,端口,数据内容
String ip = dp.getAddress().getHostAddress();//dp.getAddress()是获取IP地址对象
int port = dp.getPort();//注意,此处的端口指的不是本地端口,而是指发送源的端口,即由谁发送来的
String text = new String(dp.getData(),0,dp.getLength());//用于存储的buf数组是1024大小,但是实际可能很小,因此将其有效位变为字符串返回
System.out.println(ip+":"+port+":"+text);
if (text.equals("over")){
System.out.println(ip+"...退出聊天室");
}
}
}catch(Exception e){

}
}
}


主程序

public class ChatDemo {
public static void main(String[] args) throws SocketException {
DatagramSocket send = new DatagramSocket();
DatagramSocket rece = new DatagramSocket(10001);//注意发送端可以不指定端口,但是接收端必须指定端口
new Thread(new Send(send)).start();
new Thread(new Rece(rece)).start();
}
}




由于地址使用的是127.0.0.1为本地主机地址,因此只实现了本地单向的一个功能,那么如何实现局域网内群聊的功能?

只要改变这个ip地址就可以了,以如下c类地址(有三个字节的网络号字段,最前面的3位是(110),还有21位可以进行分配)举例:



子网掩码3个255代表IP地址中的192.168.1为网络位,即代表当前所处的192.168.1这个网络,后面一位是ip地址位,从0到255,其中0不能使用,其代表网络位,即192.168.1网段;255代表广播地址,如为192.168.1.255,则会将信息发送到192.168.1网段的所有机器上,因此使用255即可实现局域网内的群聊功能,将上述程序中的127.0.0.1改为192.168.1.255即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  网络编程 UDP