天天看点

黑马程序员:网络编程之UDP传输

---------------------- android培训、 java培训、期待与您交流! ----------------------

网络编程:

· 网络模型

  • OSI参考模型
  • TCP/IP参考模型

·网络通讯要素

  1. IP地址:InetAddress对象
  • 网络中设备的标识
  • 不易记忆,可用主机名。
  • 本地回环地址:127.0.0.1 主机名:localhost
  1. 端口号
  • 用于标识进程的逻辑地址,不同进程的标识。
  • 有效端口:0~65535,其中0~1024系统使用或保留端口。
  1. 传输协议
  • 通讯的规则
  • 常见的协议:TCP,UDP

-------------------------------------------------------------------------------------------------------------

UDP

  • 将数据及源和目的封装成数据包,不需建立连接
  • 每个数据包的大小限制在64k内
  • 因为无连接所以是不可靠协议
  • 不需要建立连接所以速度快

TCP

  • 需要建立连接,形成传输数据的通道。
  • 在连接中进行大数据量传输
  • 通过三次握手完成连接,是可靠协议
  • 必须建立连接,效率会稍低

Socket

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

--------------------------------------------------------------------------------------------------------------------

UDP传输

  • ·DatagramSocket与DatagramPacket
  • ·建立发送端,接收端
  • ·建立数据包
  • ·调用Socket的发送接收方法
  • ·关闭Socket
  • ·发送端与接收端是两个独立的运行程序。
import java.net.*;
class UdpSend
{
	public static void main(String[] args) throws Exception
	{
	
	/*
	需求:(建立发送端)通过udp传输方式将一段文字数据发送出去,
	思路:1,建立UDPSocket服务
		  2. 提供数据,并将数据封装到数据中。
		  3. 通过socket服务的发送功能,将数据包发出去
		  4. 关闭资源。
	*/


		//1。建立Udp服务:DatagramSocket对象
		DatagramSocket ds = new DatagramSocket(8888);//发送端端口号可以不指定,系统自动分配。
		//2. 确定数据,并封装成数据包
		byte[] buf = ("ddddd".getBytes());
		DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);
		//3. 通过socket服务发送数据包。send方法。
		ds.send(dp);
		//4. 关闭资源
		ds.close();
	}
}


class UdpRece
{
	/*
	需求:(建立接收端)用于接收udp协议传输的数据并处理。
	思路:1. 定义udpsocket服务。通常会监听一个端口,否则系统随机分配。
		  2. 定义一个接收数据的数据包。
		  3. 通过socket服务的receive方法将受到的数据存入到定义好的数据包中。
		  4. 通过数据包对象的特有功能,将数据打印到控制台上
		  5. 关闭资源。
	*/
	public static void main(String[] args) throws Exception
	{
		//1.建立udpsocket服务,建立端点
		DatagramSocket ds = new DatagramSocket(10000);
		//循环接收
		while(true)
		{			
			//2. 定义一个数据包,用于存放接收到的数据。
			byte[] b = new byte[10];
			DatagramPacket dp1 = new DatagramPacket(b,b.length);//这句话编译时报错,无匹配构造器吗,还未搞明白原因。
			//3. 通过服务的receive方法将收到的数据储存到数据包中。
			//receive():是阻塞式方法。
			ds.receive(dp1);
			//4. 通过数据包的方法获取包中的数据
			String ip = dp1.getAddress().getHostAddress();
			String data = new String(dp1.getData(),0,dp1.getLength());
			int port = dp1.getPort();
			System.out.println("主机"+ip+":"+port+"说:"+data);
		}	
	
	}
}

           

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

利用多线程技术实现一个控制台技能接收信息也能通过键盘发送信息。

import java.io.*;
import java.net.*;
class Send implements Runnable
{
	//声明变量ds
	private DatagramSocket ds = null;
	//建立构造函数,初始化时把Socket服务传进来
	public Send(DatagramSocket ds)
	{
		this.ds = ds;
	}
	//覆盖接口run方法
	public void run()
	{
		try
		{
			//创建带缓冲的字节读取流与键盘关联
			BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
			//循环读取键盘输入的内容。
			String line = null;
			while((line=bufr.readLine())!=null)
			{
				//把读到的一行内容转换成字节数组
				byte[] buf = line.getBytes();
				//创建数据包,指定数据包要接收的字节数组,数组长度,要传送的ip地址和端口
				DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);
				//用Socket服务发送数据包中的内容
				ds.send(dp);
			}
		}
		catch (Exception e)
		{
			throw new RuntimeException("发送端异常");
		}
	}
}

class Receive implements Runnable
{	
	private DatagramSocket ds= null;
	public Receive(DatagramSocket ds)
	{
		this.ds = ds;
	}
	public void run()
	{
		try
		{
			//循环接收数据
			while(true)
			{
				//创建自己数组,udp一个数据包最大64kb所以最大一次接收64kb
				byte[] buf = new byte[1024*64];
				//创建空数据包,指定接收的字节数组对象和数组长度。
				DatagramPacket dp = new DatagramPacket(buf,buf.length);
				//用socket服务的接收方法接说数据包
				ds.receive(dp);
				//用数据包提供的方法获取接收到的ip,端口和数据。
				//注意:一般都要先获取ip,就好比接电话前要知道是谁打来的。
				String ip = dp.getAddress().getHostAddress();
				//接收数据时要指定数据包的长度,否则每次都获取整个数组的内容包括空内容。
				String data = new String(dp.getData(),0,dp.getLength());
				int port = dp.getPort();
				System.out.println(ip+":"+port+" 说:"+data);
			}		
		}
		catch (Exception e)
		{
			throw new RuntimeException("接收端异常");
		}
	}
}
class CharDemo 
{
	public static void main(String[] args) 
	{
		try
		{
			//创建发送端socket服务,端口可以指定也可以系统自动分配
			DatagramSocket sendds = new DatagramSocket();
			//创建接收端socket服务,一定要指定监听端口。
			DatagramSocket receds = new DatagramSocket(10000);
			//创建发送端对象并作为参数传递给Thread线程并开启。
			new Thread(new Send(sendds)).start();
			//创建接收端对象并作为参数传递给Thread线程并开启。
			new Thread(new Receive(receds)).start();
		}
		catch (Exception e)
		{
			throw new RuntimeException("端口监听失败");
		}
		
	}
}
           

---------------------- android培训、 java培训、期待与您交流! ----------------------详细请查看: http://edu.csdn.net/heima