zoukankan      html  css  js  c++  java
  • 网络编程__【概述】【UDP传输】【DatagramSocket & DatagramPacket】


    概述:

    1,找到对方IP

    2,数据要发送到对方指定的应用程序上,为了标识这些应用程序,给网络应用程序添加数字标识,这个数字就称之为端口

    3,定义通信规则,这个通讯规则就称为协议,国际通用的协议为TCP/IP

    网络模型
    OSI参考模型、TCP/IP参考模型


    1.物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后再转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特
    2.数据链路层:主要将从物理层接收的数据进行MAC地址(网卡的地址)的封装与解封装。常把这一层的数据叫做帧。在这一层工作的设备是交换机,数据通过交换机来传输
    3.网络层:主要将下层接收到的数据进行IP地址(例192.168.0.1)的封装与解封装。在这一层工作的设备是路由器,常把这一层的数据叫做数据包。
    4.传输层:定义了一些传输数据的协议和端口号(WWW端口号80等),如:TCP(传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据),UDP(用户数据报协议,与TCP特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如QQ聊天数据就是通过这种方式传输的)。主要是将从下层接收的数据进行分段和传输,到达目的地址后再进行重组。常常把这一层叫做段。
    5.会话层:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间发起会话或者接收会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名)
    6.表示层:主要是进行对接收的数据进行解释,加密与解密、压缩与解压缩等(也就是把计算机能够识别的东西转换成人能够识别的东西(如图片、声音等)。
    7.应用层:主要是一些终端的应用,比如说FTP(各种文件下载)、WEB(IE浏览)、QQ之类的(可以把它理解成我们在电脑屏幕上可以看到的东西,就是终端应用)。



    网络通讯要素
    IP地址
    :InetAddress
    网络中设备的标识;不易记忆,可用主机名;本地回环地址:127.0.0.1  主机名:localhost
    端口号
    用于标识进程的逻辑地址,不同进程的标识;有效端口:0~65535,其中0~1024系统使用或保留端口。

    传输协议

    通讯的规则;常见协议:TCP,UDP,二者区别如下表:

    UDP特点 TCP特点
    将数据及源和目的封装成数据包中,不需要建立连接 建立连接,形成传输数据的通道
    每个数据报的大小在限制在64k内,封包 在连接中进行大数据量传输
    因无连接,是不可靠协议 通过三次握手完成连接,是可靠协议
    不需要建立连接,速度快 必须建立连接,效率会稍低
      UDP应用:聊天、视频、桌面共享等                                 TCP应用:下载文件等应用

    Socket

    Socket就是为网络服务提供的一种机制。
    通信的两端都有Socket。
    网络通信其实就是Socket间的通信。
    数据在两个Socket间通过IO传输。

    192.168.1.0网络段
    192.168.1.255广播段,给在网段内的所有端口发布广播

    UDP传输

    DatagramSocketDatagramPacket
    1,建立发送端,接收端。
    2,建立数据包。
    3,调用Socket的发送接收方法。
    4,关闭Socket。
    发送端与接收端是两个独立的运行程序。

    发送端

    需求: 通过UDP传输,将一段文字发送出去
    思路:
    1,建立Udpsocked服务,通过DatagramSocked对象
    2,提供数据,并将数据封装到数据包中;方法:DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
    3,通过socked服务的发送功能,将数据发送出去
    4,关闭资源

    import java.net.*;
    class UdpSend //发送端
    {
    	public static void main(String[] args) throws Exception
    	{
    		DatagramSocket ds = new DatagramSocket(1234);//1,创建服务
    
    		byte[] buf = "UDP is coming".getBytes();//2,构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
    		DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.254"),10000);
    		ds.send(dp);	//3,通过socket服务发送数据包
    		ds.close();		//4,
    	}
    }

    接收端:

    需求:
    定义一个应用程序,接收UDP协议传输的数据并处理
    思路:
    1,定义Udpsocket服务,建立接收端点;监听风端口数字标识;方便于明确哪些数据需要该应用程序接收处理
    2,定义一个数据包,用来存储接收到的字节数据;数据包对象中有更多功能可以提取字节数据的不同数据信息
    3,通过socket服务的receive方法将接收到的数据存入已经定义好的数据包中
    4,通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上
    5,关闭资源

    class UdpReceive	//接收端
    {
    	public static void main(String[] args) throws Exception
    	{
    		DatagramSocket ds = new DatagramSocket(10000);//1,创建接收端点,监听吧指定端口
    		while(true)
    		{
    			byte[] buf = new byte[1024];
    			DatagramPacket dp = new DatagramPacket(buf,buf.length);//2,定义存储数据的数据包
    			ds.receive(dp);		//3、通过receive方法将接收到的数据存入数据包中
    								//线程阻塞式方法,会抛出IO异常
    			String ip = dp.getAddress().getHostAddress();//4、通过数据包方法获取其中数据
    			String data = new String(dp.getData(),0,dp.getLength());//数据
    			int port = dp.getPort();	//端口号
    			System.out.println(ip+" : "+data+" : "+port);
    //			ds.close();	//5、关闭资源
    		}
    	}
    }

    通过键盘录入完成UDP的发送和接收

    import java.net.*;
    import java.io.*;
    class UdpSend2
    {
    	public static void main(String[] args) throws Exception
    	{
    		DatagramSocket ds = new DatagramSocket();	//创建发送端
    		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//键盘录入
    		String line = null;
    		while ((line=bufr.readLine()) !=null)//阻塞式方法read
    		{
    			if("886".equals(line))
    				break;
    			byte[] buf = line.getBytes();//字节数组			封包
    			DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10086);
    			ds.send(dp);	//发送
    		}
    		ds.close();
    	}
    }
    class UdpRec
    {
    	public static void main(String[] args) throws Exception
    	{
    		DatagramSocket ds = new DatagramSocket(10086);	//创建接收端
    		while (true)
    		{
    			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);
    		}
    	}
    }

    通过UDP和多线程和IO的聊天程序

    需求:编写一个聊天程序
    分为数据发送和数据接收两部分,两部分需要同时在一个进程执行,用到多线程;两个线程分别控制发送和接收
    收和发动作不一致,所以要定义两个run方法在两个不同的类中

    import java.net.*;
    import java.io.*;
    class Send implements Runnable
    {
    	private DatagramSocket ds;
    	public Send(DatagramSocket ds){
    		this.ds = ds;
    	}
    	public void run()
    	{
    		try{
    			BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
    			String line = null;
    			while ((line=bufr.readLine()) !=null)
    			{
    				if("886".equals(line))
    					break;
    				byte[] buf = line.getBytes();		//192.168.1.255广播段,给在网段内的所有端口发布广播
    				DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10011);
    				ds.send(dp);
    			}
    		}
    		catch (Exception e){
    			throw new RuntimeException("发送失败!");
    		}
    	}
    }
    
    class Rece implements Runnable
    {
    	private DatagramSocket ds;
    	public Rece(DatagramSocket ds){
    		this.ds = ds;
    	}
    	public void run()
    	{
    		try{
    			while (true)
    			{
    				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){
    			throw new RuntimeException("接收失败!");
    		}
    	}
    }
    
    class  UdpTest
    {
    	public static void main(String[] args) throws Exception
    	{
    		DatagramSocket sendSocket = new DatagramSocket();
    		DatagramSocket receSocket = new DatagramSocket(10011);
    
    		new Thread(new Send(sendSocket)).start();
    		new Thread(new Rece(receSocket)).start();
    	}
    }




  • 相关阅读:
    基于Java的地铁线路查询系统设计思路
    个人总结05
    构建之法读书笔记03
    Java 8 (二) 新的时间API
    MySql基础笔记(三)其他重要的事情
    MySql基础笔记(二)Mysql语句优化---索引
    JavaScript基础笔记(十四)最佳实践
    JavaScript基础笔记(十三)测试和调试
    MySql基础笔记(一)Mysql快速入门
    JavaScript基础笔记(十二)Ajax
  • 原文地址:https://www.cnblogs.com/Joure/p/4337203.html
Copyright © 2011-2022 走看看