[英]What will happen if two clients send request simultaneously to a ServerSocket that is using a while loop to accept requests
[英]Unable to read and send the request simultaneously in java using serversocket
我已經編寫了這個簡單的Java服務器,可以使用服務器套接字接受端口上的連接。 我希望每當某些客戶端嘗試在同一局域網內的此端口上發送一些數據時,我想:
1.打印該數據,即:使用InputStreamReader
從inputstream讀取到緩沖區,然后打印到控制台。
2.使用OutPutStreamWriter
在outputstream上寫入,將一些數據發送回客戶端。
3.關閉兩個流,即: outputStreamWriter
和inputStreamReader
,然后最后關閉套接字。
我面臨的問題是,即使為輸入和輸出創建了兩個單獨的線程,我一次也只能執行一個。
例如,如果我從同一網絡內的任何設備在端口8086
上發出請求,則所有內容都將被阻止(造成死鎖),除非發出請求的客戶端本身取消了該請求,否則不會在控制台上打印任何內容。 同樣,如果我終止與服務器的連接,即:終止Java應用程序,則在客戶端獲得此響應字符串“成功”。
我不知道為什么即使關閉了流,流仍然沒有關閉。
我以為,如果我們在兩個不同的線程中寫入outputstream
並從inputstream
讀入,這將解決問題,但仍然沒有運氣。
有人可以幫忙嗎?
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Notification {
private Socket clientSocket;
private BufferedReader buffInputStream;
private InputStreamReader inputStreamReader;
private OutputStreamWriter outputStreamWriter;
private OutputStream outputstream;
private InputStream inputstream;
public Notification(){
}
public void start() {
Thread listenThread = new Thread(listen);
listenThread.start();
}
Runnable listen = new Runnable() {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(8086);
while(true){
clientSocket = serverSocket.accept();
Thread t2 = new Thread(inStream);
t2.start();
Thread t1 = new Thread(outStream);
t1.start();
t1.join();
t2.join();
buffInputStream.close();
inputStreamReader.close();
outputStreamWriter.close();
clientSocket.close();
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable outStream = new Runnable() {
@Override
public void run() {
try {
outputstream = clientSocket.getOutputStream();
outputStreamWriter = new OutputStreamWriter(outputstream);
outputStreamWriter.write("success");
outputStreamWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
};
Runnable inStream = new Runnable() {
@Override
public void run() {
try {
inputstream = clientSocket.getInputStream();
inputStreamReader = new InputStreamReader(inputstream);
buffInputStream = new BufferedReader(inputStreamReader);
List<String> response = new ArrayList<>();
String line;
while ((line = buffInputStream.readLine()) != null) {
response.add(line);
}
String arr[] = response.toArray(new String[response.size()]);
for (String re : arr) {
System.out.println(re);
}
}
catch (IOException e){
e.printStackTrace();
}
}
};
}
這里沒有僵局。 在對等方斷開連接之前,您的讀取線程根本不打印任何內容。 在閱讀時打印每一行,而不是在收到流末之后。 您不需要列表,數組或第二個循環。
但是,這永遠都行不通。 您正在所有客戶端之間共享一個clientSocket
引用。 您需要創建將客戶端套接字作為參數並將其存儲為實例變量的Runnables
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.