1. 程式人生 > >網絡編程UDP/TCP協議

網絡編程UDP/TCP協議

inetaddress udp tcp socket serversocket

一、網絡編程三要素

IP:網絡中設備的標識,不易記憶,可用主機名

端口號:用於標識進程的邏輯地址,不同進程的標識

傳輸協議:通訊的規則常見協議:TCP,UDP

UDP

把數據打成一個數據包 , 不需要建立連接

數據包的大小有限制不能超過64k

因為無連接,所以屬於不可靠協議(可能丟失數據)

因為無連接 ,所以效率高

TCP

需要建立連接,形成連接通道

數據可以使用連接通道直接進行傳輸,無大小限制

因為有鏈接,所以屬於可靠協議

因為有鏈接,所以效率低

二、IP以及端口號

1、InetAddress類 —— 表示互聯網協議 (IP) 地址

1)此類沒有構造方法,創建對象使用方法實現

public static InetAddress getByName(String host) //參數為主機名或者IP的字符串表現形式

2)常用方法

public String getHostAddress() 獲取IP

public String getHostName() 獲取主機名

2、cmd IP查詢

127.0.0.1 本地回環地址 用來做一些本地測試 不走交換機

ping IP地址 用來檢測本機是否可以和指定的IP地址的計算機可以進行正常通訊

ipconfig /all 用來查看IP地址

getmac 用來獲取mac地址

3、端口號 —— 邏輯端口

用來標示我們的計算機上的進程(正在運行的程序),端口號的有效範圍應該是 0-65535,其中0-1024被系統占用或者保留

三、UDP協議

1、DatagramSocket類 —— 此類表示用來發送和接收數據報包的套接字

1)構造方法:

public DatagramSocket()

public DatagramSocket(int port) //參數port 端口號

public DatagramSocket(int port,InetAddress laddr) //參數laddr IP對象

2)常用方法:

public void close()關閉此數據報套接字

public void send(DatagramPacket p)

發送數據報包

public void receive(DatagramPacket p) 接收數據報包

public InetAddress getInetAddress() 返回此套接字連接的地址。如果套接字未連接,則返回 null。

2、DatagramPacket類 —— 此類表示數據報包

1)構造方法:

public DatagramPacket(byte[] buf,int length)

//參數 buf:保存傳入數據報的緩沖區 length:一次要讀取的長度

public DatagramPacket(byte[] buf,int length,InetAddress address,int port)

//參數 buf:包數據 length:包長度 address:目的IP port:目的端口號

2)解析數據:

public byte[] getData()返回用來接收或發送數據的緩沖區

public int getLength()返回將要發送或接收到的數據的長度

3、使用UDP傳輸數據

1)客戶端:

public class SentDemo {
				public static void main(String[] args) throws IOException {
					InetAddress ip = InetAddress.getByName("接收端ip的字符串變現形式");
					DatagramSocket ds = new DatagramSocket();
					
					byte[] buf = "abc".getBytes();
					DatagramPacket dp = new DatagramPacket(buf, buf.length, ip, 6666);	//端口號不能定義成0-1024
					
					ds.send(dp);
					ds.close();
				}
			}


2)接收端:

public class ReceiveDemo {
				public static void main(String[] args) throws IOException {
					DatagramSocket ds = new DatagramSocket(6666);
					
					byte[] buf = new byte[1024];
					DatagramPacket dp = new DatagramPacket(buf, buf.length);
					
					ds.receive(dp);
					
					System.out.println(new String(dp.getData(),0,dp.getLength()));
					ds.close();
				}
			}


四、TCP協議 —— 使用管道輸入輸出流傳輸數據

1、服務器端

1)創建TCP通訊協議服務器端對象

ServerSocket ss = new ServerSocket("端口號");

2)監聽客戶端

Socket sk = ss.accept();

3)獲取管道輸入流對象

InputStream is = sk.getInputStream();

4)讀取數據 //在使用管道輸入流while循環接收數據的時候,不能以-1作為讀取完畢的判定條件

//一般循環讀取數據時,在客戶端調用shutdownOutput()方法,服務端自動跳出循環

byte[] buf = new byte[1024 * 8];

int len = is.read(buf);

System.out.println(new String(buf,0,len));

5)釋放資源

ss.close(); //一般服務器不用關閉

2、客戶端

1)創建TCP通訊協議客戶端對象

Socket sk = new Socket("服務端IP","服務端端口號");

2)獲取管道流輸出對象

OutputStream os = sk.getOutputStream();

3)寫數據

os.write("需要傳輸的內容".getBytes());

4)釋放資源

sk.close();

3、服務端反饋

服務端:

1)創建TCP通訊協議服務器端對象

2)監聽客戶端

3)獲取管道輸入流對象

4)讀取數據

5)獲取管道輸出流對象

OutputStream os = sk.getOutputStream();

6)反饋信息

os.write("已收到".getBytes());

客戶端:

1)創建TCP通訊協議客戶端對象

2)獲取管道流輸出對象

3)寫數據

4)獲取管道輸入流對象

InputStream is = sk.getInputStream();

4)接收反饋信息

byte[] buf = new byte[1024 * 8];

int len = is.read(buf);

System.out.println(new String(buf,0,len));

5)釋放資源

4、shutdownOutput()方法

當客戶端發送文件時,發送完畢後調用shutdownOutput()方法,服務端就會收到,停止接收;

sk.shutdownOutput();

5、TCP服務端多線程改進

public class TCPServerDemo {
			public static void main(String[] args) throws IOException {
				ServerSocket ss = new ServerSocket(9527) ;
				//循環監聽客戶端
				while(true){		
					Socket sk = ss.accept() ;
					// 開啟線程
					new Thread(new TCPServerThread(sk)).start() ;
				}
			}
		}
public class TCPServerThread implements Runnable {	
			private Socket sk ;
			public TCPServerThread(Socket sk){
				this.sk = sk ;
			}
			@Override
			public void run() {		
				try {		
					BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream())) ;
					BufferedWriter bw = new BufferedWriter(new FileWriter("a.java")) ;
					// 一次讀取一行
					String line = null ;
					while((line = br.readLine()) != null){
						bw.write(line) ;
						bw.newLine() ;
						bw.flush() ;
					}
					try {
						Thread.sleep(100) ;
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					// 給客戶端端反饋
					// 獲取輸出流對象
					OutputStream out = sk.getOutputStream() ;
					out.write("上傳文件成功!".getBytes()) ;
					
				} catch (Exception e) {
					e.printStackTrace() ;
				}	
			}
		}


網絡編程UDP/TCP協議