Jam*_*ord 6 java sockets multithreading inputstream
我在java中使用套接字时遇到问题.我有一个ServerSocket正在使用accept()监听并为每个客户端请求生成线程.客户端和服务器之间的通信工作正常.我正在使用输入流从serverthreads中的客户端读取数据,例如:
inputStream = mySocket.getInputStream();
bytes = inputStream.read(buffer);
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果我从客户端调用socket.close(),阻塞调用没有任何反应bytes = inputStream.read(buffer);,它会继续阻塞.但是如果我从服务器关闭套接字,然后inputStream.read(buffer);客户端返回"-1" ,它就有效.
SERVER-MAINTHREAD:
//SERVER MAIN THREAD, SPAWNS CLIENT THREADS
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
while (listening){
new ServerThread(serverSocket.accept(), monitor).start();
}
Run Code Online (Sandbox Code Playgroud)
SERVER-CLIENTTHREADS:
public class ServerThread extends Thread{
public ServerThread(Socket socket, Monitor monitor) {
this.socket = socket;
this.monitor = monitor;
}
public void run(){
byte[] buffer = new byte[1024];
int bytes;
//Listen
while(true){
try {
InputStream inputStream = socket.getInputStream();
monitor.doStuffWithOtherThreads(Object myObject);
bytes = inputStream.read(buffer); //Problem
if (bytes == -1){
System.out.println("breaks");
break;
}
byte[] readBuf = (byte[]) buffer;
String readMessage = new String(readBuf, 0, bytes);
System.out.println(readMessage);
System.out.println(bytes);
} catch (IOException e) {
System.out.println("Connection closed");
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
客户:
InetAddress serverAddr = InetAddress.getByName("serverhostname");
socket = new Socket(serverAddr, PORT);
socket.close(); //Close the socket connection from client. Nothing happens in the serverthread
Run Code Online (Sandbox Code Playgroud)
我不知道我是否理解你的问题,但我想说,由服务器关闭套接字是正常的。
在服务器端(在独立线程中),您有监听套接字:
ServerSocket socketServeur = new ServerSocket(port);
Run Code Online (Sandbox Code Playgroud)
然后可能(如果是小型服务器,在同一线程中)一个循环接受传入连接(没有异常管理,可能socket.close位于finally块中):
while (! askedToClose) {
Socket socket = socketServeur.accept();
doSomethingWithRequest(socket);
socket.close();
}
Run Code Online (Sandbox Code Playgroud)
在客户端,您有:
Socket clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(port));
OutputStream output = clientSocket.getOutputStream();
// send something to server
InputStream input = clientSocket.getInputStream(); // will block until data is available
// reading response
Run Code Online (Sandbox Code Playgroud)
服务器应该知道它何时到达请求的末尾。例如在http中它可能是(取自scala中的mockHttpServer,因此可能会出现一些错误,但过程是相同的):
void doSomethingWithRequest(Socket socket) {
BufferedReader inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream));
StreamWriter outputWriter = new OutputStreamWriter(socket.getOutputStream);
StringBuilder requestBuilder = new StringBuilder();
do {
requestBuilder.append(inputReader.read().toChar());
} while (!requestBuilder.toString().endsWith("\r\n\r\n"));
saveUri(getUriFromRequest(requestBuilder.toString()));
outputWriter.write("HTTP/1.1 200 OK\r\n\r\n");
outputWriter.flush();
inputReader.close();
outputWriter.close();
}
Run Code Online (Sandbox Code Playgroud)
编辑:我阅读了添加的代码,但我仍然不明白:
你有 3 个“套接字”:
服务器打开和关闭侦听和“接受”套接字,并且不应受到不良客户端套接字管理的影响。
然后,如果您希望服务器接受多个并发连接,您可以添加一个线程池来接受连接并处理请求和响应。
| 归档时间: |
|
| 查看次数: |
16720 次 |
| 最近记录: |