TCP/IP協議的四層模型,從底層到高層分別是:網絡接口層、網絡層、傳輸層、應用層。IP屬於網絡層,TCP/UDP屬於傳輸層。IP定位對方的主機名,端口號對應接受數據的應用程序。java
本地迴環地址:127.0.0.1 主機名:localhost 有效端口:0~65535, 其中0~1024爲系統保留端口。服務器
IP地址由InetAddress類表示。沒有構造函數,經過靜態方法獲得實例。網絡
UDP:將數據及源和目的封裝成數據包,不須要創建鏈接;每一個數據包的大小限制在64k內;因無鏈接,是不可靠協議;速度快。ide
TCP:創建鏈接,造成傳輸數據的通道;在鏈接中進行大量數據傳輸;經過三次握手完成鏈接,是可靠協議;必須創建鏈接,效率稍低。函數
Socket:網絡之間的通訊其實就是Socket之間的通訊,Socket之間經過IO進行傳輸。測試
DatagramSocket:UDP使用的Socket接口,是本地的接口;發送、接受的單位爲DatagramPacket。注意:這裏DatagramPacket裏面有get/setPort的操做,其中set爲設置此包的目的端口號,而get有兩種狀況,一種是未發送的時候獲得剛纔set的端口號,一種是在接收端獲得發送端的Socket的端口號(發送端DatagramePacket的設置的端口號)。因此getPort是Packet的獲得Port的方法,而getLocalPort是Socket獲得Port的方法。this
測試UDP傳輸簡單的數據:spa
1 package net; 2 import java.net.DatagramPacket; 3 import java.net.DatagramSocket; 4 import java.net.InetAddress; 5 //主線程爲server端接受,子線程爲client發送 6 public class TestUDP { 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 UDPClient udpClient = new UDPClient(); 10 Thread t1 = new Thread(udpClient); 11 t1.start(); 12 UDPServerFunc(); 13 } 14 static void UDPServerFunc(){ 15 try { 16 DatagramSocket dsServer = new DatagramSocket(7777); 17 System.out.println("Server DatagramSocket Port"+dsServer.getLocalPort()); 18 byte[] buf = new byte[1024]; 19 DatagramPacket dpServer = new DatagramPacket(buf, 0, buf.length); 20 dsServer.receive(dpServer); 21 System.out.println(dpServer.getAddress().getHostAddress() + " :: " 22 + new String(dpServer.getData(),0,dpServer.getLength())); 23 System.out.println("Server DatagramPacket Port"+dpServer.getPort()); 24 } catch (Exception e) { 25 e.printStackTrace(); 26 } 27 } 28 } 29 class UDPClient implements Runnable{ 30 @Override 31 public void run() { 32 try { 33 DatagramSocket dsClient = new DatagramSocket(6666); 34 System.out.println("Client DatagramSocket Port"+dsClient.getLocalPort()); 35 byte[] buf = "hello this is UDPTest".getBytes(); 36 DatagramPacket dpClient = 37 new DatagramPacket(buf, buf.length,InetAddress.getByName("localhost"), 7777); 38 Thread.sleep(1000); 39 System.out.println("Client : "+"wakeup"); 40 System.out.println("Client DatagramPacket Port"+dpClient.getPort()); 41 dsClient.send(dpClient); 42 } catch (Exception e) { 43 e.printStackTrace(); 44 } 45 } 46 }
UDP是沒有「方向」的,因此用DatagramePacket既發送數據,又接收數據。可是TCP是有「方向」的鏈接,所以用兩個類Socket 、ServerSocket分別表示客戶端和服務器端, TCP先造成Socket的「通路」,而後再經過IO流在這條通路上進行數據的傳輸。即ServerSocket先接收到客戶端的Socket,而後調用此Socket中的IO流實現數據的流傳輸。.net
1 package net; 2 //主進程中爲server 子進程中爲client 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.InputStreamReader; 8 import java.io.OutputStream; 9 import java.io.OutputStreamWriter; 10 import java.net.BindException; 11 import java.net.ServerSocket; 12 import java.net.Socket; 13 import java.net.UnknownHostException; 14 15 public class TestTCP { 16 public static void main(String[] args){ 17 try { 18 ServerSocket ssever = new ServerSocket(7777); 19 System.out.println("ServerSocket Port:" + ssever.getLocalPort()); 20 Thread tclient = new Thread(new TCPClient()); 21 tclient.start(); 22 23 Socket s1 = ssever.accept(); 24 InputStream serverIn = s1.getInputStream(); 25 OutputStream serverOut = s1.getOutputStream(); 26 System.out.println("Server : "+"connected host : "+"addr --"+s1.getInetAddress().getHostAddress() 27 +";port --"+s1.getPort()); 28 BufferedReader serverBR = new BufferedReader(new InputStreamReader(serverIn)); 29 BufferedWriter serverBW = new BufferedWriter(new OutputStreamWriter(serverOut)); 30 System.out.println("ready"); 31 // String serverStr ="aaaaaaaa";//測試數據用 32 String serverStr = serverBR.readLine(); 33 while (true) { 34 if (serverStr.equalsIgnoreCase("over")) { 35 s1.close(); 36 break; 37 } 38 System.out.println("Server receive string : " +serverStr); 39 Thread.sleep(500); 40 serverBW.write(serverStr.toUpperCase()); 41 serverBW.newLine(); 42 serverBW.flush(); 43 serverStr = serverBR.readLine(); 44 } 45 46 } catch (Exception e) { 47 System.out.println("main problem"); 48 } 49 } 50 } 51 class TCPClient implements Runnable { 52 @Override 53 public void run() { 54 try { 55 Thread.sleep(1000); 56 Socket sclient = new Socket("localhost", 7777); 57 System.out.println("Client Socket Port"+sclient.getLocalPort()); 58 BufferedReader consleBR = new BufferedReader(new InputStreamReader(System.in)); 59 BufferedWriter clientBW = new BufferedWriter(new OutputStreamWriter(sclient.getOutputStream())); 60 BufferedReader clientBR = new BufferedReader(new InputStreamReader(sclient.getInputStream())); 61 62 String consoleStr = consleBR.readLine(); 63 String receiveStr = null; 64 while(true){ 65 if (consoleStr.equalsIgnoreCase("Over")) { 66 clientBW.write("over"); 67 clientBW.newLine(); 68 clientBW.flush(); 69 break; 70 } 71 clientBW.write(consoleStr); 72 clientBW.newLine(); 73 clientBW.flush(); 74 // SOP.sop("console : "+consoleStr); 75 receiveStr = clientBR.readLine(); 76 System.out.println("Client receive string : "+receiveStr); 77 consoleStr = consleBR.readLine(); 78 } 79 clientBR.close(); 80 clientBW.close(); 81 consleBR.close(); 82 83 } catch (UnknownHostException e) { 84 System.out.println("UnknownHostException ..."); 85 } catch (InterruptedException e1) { 86 System.out.println("InterruptedException ..."); 87 }catch (BindException e2) { 88 System.out.println("BindException ..."); 89 }catch (IOException e) { 90 System.out.println("IOEcxeption ... "); 91 } 92 } 93 94 }