[英]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.