网络编程学习笔记(二)UDP协议及聊天小程序的实现
2017-05-24 10:31
931 查看
UDP协议是传输层协议,它是无连接,不保证可靠的传输层协议。那么如果要进行发送端和接收端的通讯应该如何进行?
两个基本概念:
1.Socket 套接字
Socket就是为网络服务提供的一种机制
网络通信其实就是Socket间的通信
(网络想要进行通信需要两个端点)数据在两个Socket间通过IO传输
2.UDP传输(Java中建立了一些对象对UDP进行封装,方便我们进行操作)
DatagramSocket 此类用来发送和接收数据报包的套接字
DatagramPacket 此类表示数据报包,数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证,因此是不可靠的。(构造参数中带有地址信息的DatagramPacket对象是用来发送数据报包的)
(1)建立UDP的Socket服务
(2)将要发送的数据封装到数据包中
(3)通过UDP的Socket服务将数据包发送出去
(4)关闭Socket服务
(1)建立UDP Socket服务,因为要接收数据,必须要明确一个端口号
(2)创建数据包,用于存储接收到的数据,方便用数据包对象的方法解析这些数据
(3)使用Socket服务的receive方法,将接收到的数据存储到数据包中
(4)通过数据包的方法解析数据包中的数据
(5)关闭资源
运行结果:
注意:62086指的是源端口号,即由哪个端口发送过来的
发送端
为了达到键盘输入的目的,我们这里使用BufferedReader,通过设置特殊字符串来判断是否截止,例如这里使用的“over”
接收端
主程序
由于地址使用的是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即可。
两个基本概念:
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协议【实现聊天程序】--练习
- 26-网络编程-09-网络编程(UDP协议-聊天程序)
- java网络编程学习笔记之一(TCP/IP协议与UDP协议的区别和认识)
- Java网络编程 - 基于UDP协议 实现简单的聊天室程序
- 网络编程学习笔记二(实现一个基于简单TCP的用户注册程序)
- 黑马程序员_网络编程学习笔记-->代码主要是对UDP协议的讲解
- Java学习笔记52(网络编程:UDP协议案例)
- 【Java网络编程】UDP协议实例——简单的在线聊天程序
- 【JavaSE学习笔记】网络编程_UDP协议,TCP协议
- 黑马程序员_Java基础_网络编程_UDP传输协议编程,控制台聊天程序
- Java网络编程(UDP协议-聊天程序)
- c#网络编程学习笔记02_Tcp编程(中)_简单的同步tcp聊天程序
- linux网络编程之socket(十四):基于UDP协议的网络程序
- linux网络编程之socket(十四):基于UDP协议的网络程序
- java网络编程实现一个聊天程序
- JavaSE学习笔记--网络编程之UDP
- Java UDP 网络编程 示例 -Java学习笔记(30)
- 基于UDP协议的网络程序 (学习)
- linux网络编程之socket(十四):基于UDP协议的网络程序
- JAVA 网络编程 UDP(聊天程序)