天天看點

黑馬程式員:網絡程式設計之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