JAVA——TCP连接中Socket的正确关闭方式
基本概念
TCP協議:Transmission Control Protocol 傳輸控制協議TCP是一種面向連接(連接導向)的、可靠的、基于字節流的運輸層(Transport layer)通信協議,由IETF的RFC 793說明(specified)。
Socket:網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。
建立網絡通信連接至少要一對端口號(socket)。socket本質是編程接口(API),對TCP/IP的封裝,TCP/IP也要提供可供程序員做網絡開發所用的接口,這就是Socket編程接口;HTTP是轎車,提供了封裝或者顯示數據的具體形式;Socket是發動機,提供了網絡通信的能力。
需求分析
?* 1,客戶端
?* ? ? ?創建Socket連接服務器(指定IP地址,端口號)通過IP地址找到對應的服務器
?* ? ? ?調用Socket的getInputStream()和getOutputStream()方法獲取和服務器端相連的IO流
?* ? ? ?輸入流可以讀取服務器端輸出流寫出的數據
?* ? ? ?輸出流可以寫出數據到服務端的輸入流
?*?
?* 2,服務端
?* ? ? ?創建ServerSocket(需要指定端口號)
?* ? ? ?調用ServerSocket的accept()方法接受一個客戶端請求,得到一個Socket
?* ? ? ?調用Socket的getInputStream()和getOutputStream()方法獲取和客戶端相連的IO流
?* ? ? ?輸入流可以讀取客戶端輸出流寫出的數據
?* ? ? ?輸出流可以寫出數據到客戶端的輸入流?
問題分析
在使用socket時,需要約定好雙方讀寫完成的條件,然后關閉輸入輸出流:
socket.shutdownInput();
socket.shutdownOutput();
即當一方寫入完成后,調用shutdownOutput關閉輸出流,這時候對方的read方法就會返回-1,這時候對方就知道你寫完了,對方可以關閉輸入流,然后等待對方寫入完成調用shutdownOutput后己方再調用shutdownInput,雙方就正常關閉了輸入輸出流,這時候socket就不會出現異常了。
源代碼
Server端
public class OioServer {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(8080);while (true) {Socket socket = serverSocket.accept();System.out.println("socket = " + socket);new Thread(() -> {try {InputStream in = socket.getInputStream();OutputStream out = socket.getOutputStream();out.write("hello! I get your message that is follow".getBytes(Charset.forName("UTF-8")));byte[] buf = new byte[1024];int len;while ((len = in.read(buf)) != -1) {System.out.print(new String(buf, 0, len, Charset.forName("UTF-8")));out.write(buf, 0, len);}out.write("\n end \n".getBytes(Charset.forName("UTF-8")));out.flush();socket.shutdownInput();socket.shutdownOutput();} catch (IOException e) {e.printStackTrace();}finally {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}).start();}} }Client端
public class OioClient {public static void main(String[] args) throws IOException {Socket socket = new Socket("127.0.0.1", 8080);InputStream in = socket.getInputStream();new Thread(() -> {BufferedInputStream bufferIn = new BufferedInputStream(in);byte[] buf = new byte[1024];try {int len;while ((len = bufferIn.read(buf)) != -1) {System.out.print(new String(buf, 0, len, Charset.forName("UTF-8")));}}catch (Exception e) {e.printStackTrace();}try {socket.shutdownInput();socket.close();} catch (IOException e) {e.printStackTrace();}}).start();OutputStream out = socket.getOutputStream();int cout = 10;while (cout-- > 0) {out.write(("this time is " + System.currentTimeMillis() + "\n").getBytes("UTF-8"));}socket.shutdownOutput();} }常見異常
java.net.SocketException:socket is closed
錯誤提示的出現場景:
自己主動關閉了socket,但是之后還從里面讀寫數據
Software caused connection abort: socket write error
錯誤提示的出現場景:
對方已經關閉socket,依舊向對方寫數據
connection reset (by peer)
錯誤提示出現的場景:
一端socket被關閉,另一端仍然發送數據,發送的第一個數據包 connection reset by peer
一端socket退出,退出時為關閉連接,另一端讀數據 connection reset
參考文章
https://stackoverflow.com/questions/14010194/detecting-socket-disconnection
https://blog.csdn.net/qq_36666651/article/details/84191732
https://blog.csdn.net/qq_41264055/article/details/81353907
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的JAVA——TCP连接中Socket的正确关闭方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EXE4J(Windows Launch
- 下一篇: 赫夫曼编码-译码器(Huffman Co