中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中socket使用getInputStream()阻塞問題怎么解決

發布時間:2021-12-13 17:08:33 來源:億速云 閱讀:938 作者:iii 欄目:開發技術

這篇文章主要介紹“Java中socket使用getInputStream()阻塞問題怎么解決”,在日常操作中,相信很多人在Java中socket使用getInputStream()阻塞問題怎么解決問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java中socket使用getInputStream()阻塞問題怎么解決”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

socket使用getInputStream()阻塞

今天用socket進行編程練習時,發現程序到了getInputStream()這里就進行不下去了

Socket socket = new Socket("127.0.0.1", 800);
ObjectInputStream reader = new ObjectInputStream(socket.getInputStream());
System.out.println("a");
ObjectOutputStream writer = new ObjectOutputStream(socket.getOutputStream());

就這樣的一個測試代碼,a不會打印出來

后來發現是getInputStream()會一直阻塞在那里阻塞

我把兩行代碼調了一下就好了,還不太清楚原因,先記下來

Socket socket = new Socket("127.0.0.1", 800);
ObjectOutputStream writer = new ObjectOutputStream(socket.getOutputStream());
System.out.println("a");
ObjectInputStream reader = new ObjectInputStream(socket.getInputStream());

用線程解決Socket的getInputStream阻塞

1.背景

在Socket通信中,當我們希望傳輸對象時,往往會用到輸入/輸出對象流。

ObjectInputStream in=new ObjectInputStream(socket.getInputStream());
ObjectOutputStream out=new ObjectOutputStream(socket.getOutputStream());

2.問題

當程序調用socket.getInputStream()程序被被卡住。

3.原因

socket.getInputStream()方法會導致程序阻塞,直到inputStream收到對方發過來的報文消息,程序才會繼續往下執行。

public ObjectInputStream(InputStream in) throws IOException的官方API顯示:

Creates an ObjectInputStream that reads from the specified InputStream. A serialization stream header is read from the stream and verified. This constructor will block until the corresponding ObjectOutputStream has written and flushed the header. [1]

4.解決辦法

用線程的方式處理輸入流。以下為示例代碼:

//===============客戶端代碼 SocketClient.java=====================

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException; 
 
public class SocketClient {
	private Socket socket;
	private ObjectOutputStream out;
	private ObjectInputStream in;	
	public SocketClient(){
		try {
			socket=new Socket("localhost",8081);
			out=new ObjectOutputStream(socket.getOutputStream());
			ReadThread readThread=new ReadThread();
			readThread.start();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void sendMessage(String msg){
		System.out.println("send message:"+msg);
		try {
			out.writeObject(msg);
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	class ReadThread extends Thread{
		boolean runFlag=true;
		public void run(){
			try {
				in=new ObjectInputStream(socket.getInputStream());
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			while(runFlag){
				if(socket.isClosed()){
					return;
				}
				try {
					Object obj=in.readObject();
					if(obj instanceof String){
						System.out.println("Client recive:"+obj);
					}
				} 
				catch (IOException e) {
					e.printStackTrace();
				} 
				catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}
		}
		
		public void exit(){
			runFlag=false;
		}
	}
	
	public static void main(String[] args) {
		SocketClient socketClient=new SocketClient();
		System.out.println("build socketClient");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		socketClient.sendMessage("Hello first.");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		socketClient.sendMessage("Hello second.");
	} 
}

//============服務器端代碼 SocketService.java===========

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Date;
 
public class SocketService {
	ServerSocket serverSocket;	
	public SocketService(){
		try {
			serverSocket=new ServerSocket(8081);
			while(true){
				Socket socket=serverSocket.accept();
				SocketServiceThread sst=new SocketServiceThread(socket);
				sst.start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	class SocketServiceThread extends Thread{
		Socket socket;
		ObjectInputStream in;
		ObjectOutputStream out;
		boolean runFlag=true;
		public SocketServiceThread(Socket socket){
			if(null==socket){
				runFlag=false;
				return;
			}
			this.socket=socket;
			try {
				out=new ObjectOutputStream(socket.getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void run(){
			if(null==socket){
				System.out.println("socket is null");
				return;
			}
			try {
				in=new ObjectInputStream(socket.getInputStream());
				while(runFlag){
					if(socket.isClosed()){
						System.out.println("socket is closed");
						return;
					}
					try {
						String obj=(String)in.readObject();
						if(obj instanceof String){
							System.out.println("Server recive:"+obj);
							Date date=new Date();
							out.writeObject("["+date+"]"+obj);
							out.flush();
						}
						else{
							System.out.println("Server recive:"+obj);
						}
					} 
					catch (ClassNotFoundException e) {
						e.printStackTrace();
					}
					catch (SocketException e){
						e.printStackTrace();
						return;
					}
					catch (IOException e){
						e.printStackTrace();
					}
				}
			} catch (IOException e1) {
				e1.printStackTrace();
				return;
			} catch (Exception e){
				return;
			}
		}
		
		public void exit(){
			runFlag=false;
		}
	}
	
	public static void main(String[] args) {
		System.out.println("===============start service===============");
		new SocketService();
	} 
}

5.Socket通信注意事項

(1).writeXXX()方法后一般用flush()來把緩存內容發送出去。

(2).發送對象時,對象必須串行化,即該對象需要實現Serializable接口。

到此,關于“Java中socket使用getInputStream()阻塞問題怎么解決”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

清苑县| 钟山县| 柳州市| 乌兰察布市| 桃江县| 卓尼县| 呼伦贝尔市| 咸宁市| 巴彦县| 勐海县| 和静县| 平和县| 武威市| 平定县| 南部县| 体育| 望江县| 大方县| 古浪县| 张家口市| 哈尔滨市| 南澳县| 嵩明县| 嘉峪关市| 永胜县| 南木林县| 黔东| 城口县| 鄢陵县| 茶陵县| 松原市| 开原市| 开远市| 闽清县| 隆林| 宾阳县| 岱山县| 永登县| 扎赉特旗| 壤塘县| 长白|