TCP/UDP套接字 java socket編程實例
網絡協議七層結構:
什麽是Socket?
socket(套接字)是兩個程序之間通過雙向信道進行數據交換的端,可以理解為接口。使用socket編程也稱為網絡編程,socket只是接口並不是網絡通信協議。
HTTP協議和Socket的區別
http協議是應用層,其模式是請求-應答,客戶端發送請求,服務器端進行響應。傳輸的數據是原始格式的數據,eg :json、xml、text等數據格式。
socket不是協議是接口,socket提供TCP/UDP socket 的實例,供java 或者其他語言操作數據的傳輸,socket是對傳輸層(TCP/UPD協議)的封裝。
Socket通信分為兩種
TCP Socket :使用流傳輸,提供inputStream 和 outputStream 方法對數據進行流操作。要理解TCP套接字首先要對TCP協議有所理解。
1)TCP協議是傳輸層的協議,他的下一層是IP協議(網絡層),IP協議在網絡數據傳輸是通過ip尋址,將源地址和目的地址進行連接。TCP協議是在IP協議上多加一層端口尋址,光只通過IP尋址只能定位到主機,tcp通過端口找到對應的應用程序。
2)TCP 建立連接需要三次握手,將源應用程序和目的應用程序之間搭建一個連接,所以源應用和目的應用程序之間必須是one by one。IP 協議只管數據的傳輸,不保證數據是否丟失,重復傳,順序是否正確,TCP會對這些問題做一些補償機制,丟失數據重傳,用隊列保證數據的順序。
3) TCP 缺點:因為每個客戶端和服務器端傳輸數據都要建立連接,三次握手是不傳輸數據並且有耗時,當有大量短連接的時候並且對數據的正確性要求不高的時候,將會占用帶寬。
UDP Socket:使用數據報文進行傳輸,創建UDP socket 發送和接收數據報文。
1)UDP協議同TCP協議一樣都是應用層協議,也是通過端口尋址,找到對應的應用程序。
2)UDP傳輸數據報文不需要和目的應用程序建立連接,他在數據報文中指定目的主機和目的端口號,發送出的數據自動尋址到對應的主機和端口號。因為不用和目的主機建立連接,所以一個源應用程序可以以廣播的形式將數據報文傳輸給多主機。因為不用建立連接,耗時和帶寬占用量都比TCP協議更優秀
3)UDP缺點:數據有可能丟失,丟失的數據不會重傳
java socket 實例
TCP Socket client
package socket.transmission.tcp; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; //TCP 套接字 客戶端負責發送請求 public class TcpClient { private static final int BUF_SIZE=32; /** * TCP客戶端發送一個請求要有三個步驟: * 1.創建一個socket的實例,創建一個指向server主機ip和端口號的TCP連接 * 2.通過套接字的輸入和輸出流進行通信 * 3.使用socket close關閉 */ public static void main(String[] args){ String ip="192.168.197.1"; int port=8080; try { // 創建一個socket實例 Socket socket=new Socket(ip,port); System.out.println("創建一個socket連接"); InputStream inputStream=socket.getInputStream(); OutputStream outputStream=socket.getOutputStream(); //向socket中寫入數據 outputStream.write("this is a word".getBytes()); int totalByrecive=0; //到目前為止接收到的數據 byte[] readBuff=new byte[BUF_SIZE]; int lastReadByte; //最後接收的字節 System.out.println("從服務器中接收的數據:"); int receiveMsgSize; while ((receiveMsgSize=inputStream.read(readBuff))!=-1){ System.out.println(new String(readBuff)); } socket.close(); //關閉 } catch (IOException e) { e.printStackTrace(); } } }
tcp sokect server
package socket.transmission.tcp; //TCP 服務器端進行接收請求 import sun.java2d.pipe.OutlineTextRenderer; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; /** * TCP服務器對客戶端發送的請求會進行以下處理 * 1.創建serverSocket實例並且指定本機端口,功能:監聽指定端口發送過來的連接 * 2.重復執行: * 1).調用的serverSocket 的accept() 監聽客戶端發送過來的請求,並創建socket * 2).使用socket的inputStream 和 outputStream 進行通訊 * 3).通信完使用socket.close() 方法將連接關閉 */ public class TcpServer { private static final int BUF_SIZE=32; public static void main(String[] args){ int port=8080; Socket socket = null; InputStream inputStream = null; OutputStream outputStream = null; try { ServerSocket serverSocket=new ServerSocket(port);//創建一個socket實例用於監聽客戶端發送的連接 System.out.println("創建serverSocket 實例"); int reviceMsgSize; // 接收msg的大小 byte[] receiveBuf=new byte[BUF_SIZE]; //創建一個信息接收的緩沖區 System.out.println("開始處理接收的數據"); while (true) { socket = serverSocket.accept(); //接收客戶端的連接 SocketAddress socketAddress = socket.getRemoteSocketAddress(); // System.out.println("訪問的地址:" + socketAddress); inputStream = socket.getInputStream(); outputStream = socket.getOutputStream(); while ((reviceMsgSize = inputStream.read(receiveBuf)) != -1) { System.out.println(new String(receiveBuf)); outputStream.write("aaaaa".getBytes(), 0, 4); } outputStream.flush(); socket.close(); } } catch (IOException e) { e.printStackTrace(); }finally { try { if(socket!=null){ socket.close(); } if(inputStream!=null){ inputStream.close(); } if(outputStream!=null){ outputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
TCP/UDP套接字 java socket編程實例