Socket類的getInputStream方法與getOutputStream方法的使用
Socket類的getInputStream方法與getOutputStream方法的使用
客戶端上的使用
- getInputStream方法可以得到一個輸入流,客戶端的Socket物件上的getInputStream方法得到輸入流其實就是從伺服器端發回的資料。
- getOutputStream方法得到的是一個輸出流,客戶端的Socket物件上的getOutputStream方法得到的輸出流其實就是傳送給伺服器端的資料。
伺服器端上的使用
getInputStream方法得到的是一個輸入流,服務端的Socket物件上的getInputStream方法得到的輸入流其實就是從客戶端傳送給伺服器端的資料流。
getOutputStream方法得到的是一個輸出流,服務端的Socket物件上的getOutputStream方法得到的輸出流其實就是傳送給客戶端的資料。
read()阻塞
從Socket上讀取對端發過來的資料一般有兩種方法:
1)按照位元組流讀取
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
int r = -1;
List<Byte> l = new LinkedList<Byte>();
while ((r = in.read()) != -1) {
l.add(Byte.valueOf((byte) r));
}
2)按照字元流讀取
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String s;
while ((s = in.readLine()) != null) {
System.out.println("Reveived: " + s);
}
這兩個方法read()和readLine()都會讀取對端傳送過來的資料,如果無資料可讀,就會阻塞直到有資料可讀。或者到達流的末尾,這個時候分別返回-1和null。
這個特性使得程式設計非常方便也很高效。
但是這樣也有一個問題,就是如何讓程式從這兩個方法的阻塞呼叫中返回。
總結一下,有這麼幾個方法:
- 傳送完後呼叫Socket的shutdownOutput()方法關閉輸出流,這樣對端的輸入流上的read操作就會返回-1。
注意不能呼叫socket.getInputStream().close()。這樣會導致socket被關閉。
當然如果不需要繼續在socket上進行讀操作,也可以直接關閉socket。
但是這個方法不能用於通訊雙方需要多次互動的情況。 - 傳送資料時,約定資料的首部固定位元組數為資料長度。這樣讀取到這個長度的資料後,就不繼續呼叫read方法。
- 為了防止read操作造成程式永久掛起,還可以給socket設定超時。
如果read()方法在設定時間內沒有讀取到資料,就會丟擲一個java.net.SocketTimeoutException異常。
例如下面的方法設定超時3秒。
socket.setSoTimeout(3000);
程式碼例項:
public class TCPClient {
public static void main(String[] args)throws IOException {
Socket socket = new Socket("127.0.0.1",5000);
OutputStream out = socket.getOutputStream();
//建立檔案物件 如果檔案路徑寫錯 Client報找不到檔案異常,Server報Connection Reset異常
File file = new File("E:\\Pictures\\010.jpg");
//位元組輸入流,讀取本地檔案到java程式中
FileInputStream fis = new FileInputStream(file);
byte[] data = new byte[1024]; //陣列,增強傳輸效率
int len = 0;
while((len = fis.read(data)) != -1) //read方法返回陣列的有效字元個數
out.write(data, 0, len);
socket.shutdownOutput(); //資料傳輸完畢,關閉socket輸出流,避免伺服器端read方法阻塞
InputStream in = socket.getInputStream(); //位元組輸入流,讀取伺服器返回的資料
len = in.read(data);
System.out.println(new String(data,0,len));
socket.close();
fis.close();
}
}
---------------------------------------------------------------------------------
public class TCPServer {
public static void main(String[] args)throws IOException {
ServerSocket server = new ServerSocket(5000);//開啟伺服器制定埠,等待客戶端連線
//獲得與伺服器相連的套接字物件 套接字:繫結ip地址和埠號的網路物件
Socket socket = server.accept();
//檢視該地址資料夾是否存在,如果不存在,建立一個
File file = new File("E:\\TestFolder\\upload");
if(!file.exists()){
boolean b = file.mkdirs();
System.out.println(b);
}
InputStream in = socket.getInputStream(); //套接字的位元組輸入流,讀取客戶端傳過來的資料
String name = System.currentTimeMillis()+""+new Random().nextInt(9999); //隨機檔名
FileOutputStream fos = new FileOutputStream(file+File.separator+name+".jpg"); //File.separator表示分隔符,windows是\,linux是/
byte[] data = new byte[1024];
int len = 0;
//如果客戶端沒有關閉socket輸出流,這裡的read方法會一直讀取,對於socket流沒有流末尾之說,不可能返回-1
while((len = in.read(data)) != -1)
fos.write(data, 0, len);
data = "上傳成功!".getBytes(); //字串轉化為位元組陣列
OutputStream out = socket.getOutputStream(); //建立位元組輸出流
out.write(data); //寫入上傳成功 ,反饋給客戶端
server.close();
fos.close();
}
}
相關文章
- String類中的equals方法與Object類中的equals方法的不同點Object
- java中String類常用方法的使用與例項Java
- 14 #### 方法分類與使用場景(繫結、靜態、類方法)
- 淺談 Dart 類與類的基本方法Dart
- 友元類的使用方法
- javaSE-day04--ArrayList基本用方法、類內定義方法和方法過載、靜態方法static(類的方法)、工具方法(static)的定義和使用Java
- ElasticSearch與SpringBoot的整合與JPA方法的使用ElasticsearchSpring Boot
- Python中類的建立和使用方法Python
- 深入剖析 Java 類屬性與類方法的應用Java
- 16 ##### 適合類方法的場景:方法內部如果需要使用當前類的話
- 管理 Windows 例項的高效方法 —— 使用 WindowExtensions 類Windows
- String 類的 substring () 方法
- Java的方法Scanner類Java
- String類常用的方法
- python類中的方法Python
- 建立Arkts的類,方法
- 張量的建立與使用方法
- StringBuffer類的delete()方法和deleteCharAt()方法的區別delete
- ES6中類的靜態方法=> static 的使用
- JS 物件合併與克隆方法的分類與比較JS物件
- 常用介面分類與模組設計的方法
- iOS Swift結構體與類的方法排程iOSSwift結構體
- socket 的使用
- Python_11 類的方法Python
- 對類物件的方法操作物件
- 【轉】Object類的常用方法Object
- Spring方法注入的使用與實現原理Spring
- MAMP 中的 Mysql 和 redis 都是 unix socket 時的配置方法MySqlRedis
- 西瓜種類與挑選方法
- Python科普系列——類與方法(下篇)Python
- Python科普系列——類與方法(上篇)Python
- wait()方法與await()方法的區別AI
- Java StringTokenizer 類使用方法概述Java
- Python中,類的特殊方法與內建函式的關聯Python函式
- 初次使用CxImage類庫、VC6配置UNICODE的方法Unicode
- 【JAVA】筆記(6)--- toString方法;equals方法;finalize方法;package與import;內部類;Java筆記PackageImport
- Python unittest.TestLoader()類的幾種尋找testcase的方法的使用Python
- 類方法