使用套接字解决此问题。我写了Http和TCP服务器的实现。 HTTP完全可以正常工作,因此我可以将请求一一发送到服务器。关于TCP服务器,不能说什么,第一个请求离开并被正确处理,但是当您尝试发送以下请求时,将引发此异常:
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:134)
at java.io.DataOutputStream.writeBytes(DataOutputStream.java:276)
at Main.main(Main.java:24)
此后,客户端关闭,服务器端继续工作。HTTP和TCP是从同一Server类实现的,从而启动服务器。
MyServer:
public abstract class Server implements Runnable {
private final Socket clientSocket;
public Server(Socket clientSocket) {
this.clientSocket = clientSocket;
}
@Override
public void run() {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
BufferedWriter output = new BufferedWriter(new PrintWriter(clientSocket.getOutputStream()))) {
String req = getRequest(reader);
setResponse(output, req);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
启动服务器的类:
public class RunServer extends Thread {
private final int port;
private ExecutorService executorService;
private String serverType;
private ServerFactoryContainer serverFactoryContainer;
public RunServer(String serverType, int port) {
this.port = port;
this.executorService = Executors.newFixedThreadPool(4);
this.serverType = serverType;
this.serverFactoryContainer = new ServerFactoryContainer();
}
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(port);
while (!isInterrupted()) {
Socket clientSocket;
try {
clientSocket = serverSocket.accept();
executorService.execute(serverFactoryContainer.getServerFactory(serverType).createServer(clientSocket));
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
TCP客户端:
public class Main {
public static void main(String[] args) throws IOException {
String req;
String resp;
try (Socket clientSocket = new Socket(InetAddress.getLocalHost(), Constants.ServerConstant.TCP_PORT);
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
while (true) {
System.out.println("Write command [get count] or [get item]");
req = inFromClient.readLine().toLowerCase();
outToServer.writeBytes(req + "\n"); // I get an exception here when I send a request to the server
resp = inFromServer.readLine();
if (!resp.isEmpty()) {
System.out.println(resp);
}
if (req.equals("exit")) {
System.exit(1);
}
}
}
}
为什么当我重新向TCP服务器提交请求时,我得到上面指示的异常?为什么在向HTTP服务器发送第二个请求时没有抛出该异常?
@Override
protected String getRequest(BufferedReader input) throws IOException {
return input.readLine();
}
@Override
protected void setResponse(BufferedWriter output, String request) throws IOException {
String result = serverCommandController.execute(RequestParser.tcpParserCommand(request));
output.write(result);
output.flush();
}
答案 0 :(得分:1)
您要在完成客户端之前关闭客户端连接。在您的服务器类中尝试以下操作:
@Override
public void run()
{
try (BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); BufferedWriter output = new BufferedWriter(new PrintWriter(clientSocket.getOutputStream())))
{
while (clientSocket.isConnected())
{
String req = getRequest(reader);
setResponse(output, req);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
clientSocket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
答案 1 :(得分:0)
您的服务器在发送响应后似乎关闭了套接字。此后,如果不打开新连接,客户端将无法发送其他请求。通常,服务器允许客户端控制连接的命运,以便客户端可以发送多个请求。您的客户端可以发送“关闭”请求,以向服务器表明客户端打算关闭套接字,并且不希望响应。