Socket簡單實現數據交互及上傳


  

聲明:本文為原創,如需轉載請說明出處:http://www.cnblogs.com/gudu1/p/7669175.html 

 

  首先為什么要寫這個呢?因為在幾個月之前我還使用Socket做一個小項目,而在今天我回想起Socket的操作細節,在我腦海里使勁挖掘Socket的痕跡,竟然絲毫沒有找到,所以立即寫了一個小Demo來記錄一下,有些東西長時間不用肯定要忘的,人的腦容量有限,跟電腦緩存一樣,不夠用的時候會把那些不用的占內存的給釋放掉, 就到這吧,說正題。

 

    Socket 和 ServerSocket 的官方API解釋:

    Socket : 此類實現客戶端套接字(也可以就叫“套接字”)。套接字是兩台機器間通信的端點。

    ServerSocket:此類實現服務器套接字。服務器套接字等待請求通過網絡傳入。它基於該請求執行某些操作,然后可能向請求者返回結果。

  套接字的實際工作由 SocketImpl 類的實例執行。應用程序通過更改創建套接字實現的套接字工廠可以配置它自身,以創建適合本地防火牆的套接字。

 

  在這個Demo中我使用了java.net包下的兩個類:Socket 和 ServerSocket ,使用到的自定義類有3個:Service 、 Client 、ServiceThread,下面配合代碼來解釋一下

 

  ServiceThread.java ,就把它當做一個服務器處理程序就好了

import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.io.IOException; import java.io.*; public class ServiceThread implements Runnable { Socket s = null; public ServiceThread(Socket socket) { // ① super(); this.s = socket; } @Override public void run() { String ip = s.getInetAddress().getHostName(); // ② System.out.println("ip:"+ip); try{ InputStream is = s.getInputStream(); // ③ byte[] buf = new byte[1024]; int len = 0; File file = new File("D:/heheCopy.java"); // ④ OutputStream os = new FileOutputStream(file); System.out.println("開始上傳"); while((len = is.read(buf)) != -1){ // ⑤ os.write(buf,0,len); // ⑥ } System.out.println("上傳完畢"); is.close(); os.close(); } catch (Exception e){ e.printStackTrace(); } } }

 

  

   ① :類只有一個構造函數,參數是Socket對象(即一個用戶),因為在服務器和客戶端是通過 I/O 流來交互,所以服務器端要獲取客戶端的IO對象(即輸入輸出流)。

  ②: 獲取客戶端的IP地址

  ③: 獲取客戶端的輸入流,

  ④: 創建一個File對象,並指定客戶端傳輸過來的數據存放的位置,如果不存在該文件就自動創建

  ⑤: 開始從流中讀取數據,並存放在byte數組緩沖區中,在客戶端的輸出流未寫入之前此方法一直處於阻塞狀態(即等待狀態)

  ⑥: 開始寫入服務器本地文件

 

  Client.java ,當做一個客戶端

public class Client { public static void main(String[] args) throws Exception { Socket s = new Socket("127.0.0.1", 10001); // ① InputStream is = new FileInputStream("D:/hehe.java"); // ② byte[] buf = new byte[1024]; int len = 0; while((len = is.read(buf))!=-1){ s.getOutputStream().write(buf,0,len); // ③ } s.shutdownOutput(); // ④ System.out.println("讀取完畢"); is.close(); } }

 

 

   ①: 創建 Socket 對象,傳入要連接服務器的 IP 和 端口

  ②: 創建一個輸入流對象讀取要上傳的文件路徑

  ③: 獲取 Socket 輸出流對象並將讀取到的數據寫入輸出流中

  ④: 任何以前寫入的數據都將被發送,如果不調用這個方法,那么在服務器端就不會知道數據已經傳輸完畢,將繼續調用此 Socket 輸入流的 read 方法,那么此時客戶端只是一個Java程序,已經執行完畢,虛擬機將釋放資源,這時,此Socket已經被 close掉,程序將拋出 SocketException 異常。

 

  Serivce.java ,服務器

public class Service{ public static void main(String[] args)throws Exception{ ServerSocket ss = new ServerSocket(10001); // ① while(true){ Socket s = ss.accept(); // ② new Thread(new ServiceThread(s)).start(); // ③ } } }

 

  

  ①: 創建服務器對象,指定該服務器的端口號

  ②: 獲得請求連接到該服務器的客戶端對象Socket

  ③: 啟動服務器處理程序線程,因為程序是無限循環,所以每當一個客戶端連接進來都會創建一個新的線程

 

 

   

           The End。。。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM