日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JAVA——TCP连接中Socket的正确关闭方式

發(fā)布時間:2024/10/5 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA——TCP连接中Socket的正确关闭方式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

基本概念

TCP協(xié)議:Transmission Control Protocol 傳輸控制協(xié)議TCP是一種面向連接(連接導(dǎo)向)的、可靠的、基于字節(jié)流的運輸層(Transport layer)通信協(xié)議,由IETF的RFC 793說明(specified)。

Socket:網(wǎng)絡(luò)上的兩個程序通過一個雙向的通信連接實現(xiàn)數(shù)據(jù)的交換,這個連接的一端稱為一個socket。

建立網(wǎng)絡(luò)通信連接至少要一對端口號(socket)。socket本質(zhì)是編程接口(API),對TCP/IP的封裝,TCP/IP也要提供可供程序員做網(wǎng)絡(luò)開發(fā)所用的接口,這就是Socket編程接口;HTTP是轎車,提供了封裝或者顯示數(shù)據(jù)的具體形式;Socket是發(fā)動機,提供了網(wǎng)絡(luò)通信的能力。

需求分析

?* 1,客戶端
?* ? ? ?創(chuàng)建Socket連接服務(wù)器(指定IP地址,端口號)通過IP地址找到對應(yīng)的服務(wù)器
?* ? ? ?調(diào)用Socket的getInputStream()和getOutputStream()方法獲取和服務(wù)器端相連的IO流
?* ? ? ?輸入流可以讀取服務(wù)器端輸出流寫出的數(shù)據(jù)
?* ? ? ?輸出流可以寫出數(shù)據(jù)到服務(wù)端的輸入流
?*?
?* 2,服務(wù)端
?* ? ? ?創(chuàng)建ServerSocket(需要指定端口號)
?* ? ? ?調(diào)用ServerSocket的accept()方法接受一個客戶端請求,得到一個Socket
?* ? ? ?調(diào)用Socket的getInputStream()和getOutputStream()方法獲取和客戶端相連的IO流
?* ? ? ?輸入流可以讀取客戶端輸出流寫出的數(shù)據(jù)
?* ? ? ?輸出流可以寫出數(shù)據(jù)到客戶端的輸入流?

問題分析

在使用socket時,需要約定好雙方讀寫完成的條件,然后關(guān)閉輸入輸出流:

socket.shutdownInput();

socket.shutdownOutput();

即當(dāng)一方寫入完成后,調(diào)用shutdownOutput關(guān)閉輸出流,這時候?qū)Ψ降膔ead方法就會返回-1,這時候?qū)Ψ骄椭滥銓懲炅?#xff0c;對方可以關(guān)閉輸入流,然后等待對方寫入完成調(diào)用shutdownOutput后己方再調(diào)用shutdownInput,雙方就正常關(guān)閉了輸入輸出流,這時候socket就不會出現(xiàn)異常了。

源代碼

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

錯誤提示的出現(xiàn)場景:

自己主動關(guān)閉了socket,但是之后還從里面讀寫數(shù)據(jù)

Software caused connection abort: socket write error

錯誤提示的出現(xiàn)場景:

對方已經(jīng)關(guān)閉socket,依舊向?qū)Ψ綄憯?shù)據(jù)

connection reset (by peer)

錯誤提示出現(xiàn)的場景:

一端socket被關(guān)閉,另一端仍然發(fā)送數(shù)據(jù),發(fā)送的第一個數(shù)據(jù)包 connection reset by peer

一端socket退出,退出時為關(guān)閉連接,另一端讀數(shù)據(jù) 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位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的JAVA——TCP连接中Socket的正确关闭方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。