Java套接字编程:关闭套接字后连接重置?
我目前正在编写一个简单的TCP聊天客户端-服务器应用程序,它可以与套接字一起工作。客户机连接到服务器,一旦被接受,就会创建一个新的工作线程来侦听客户机输入。连接到服务器(端口8818处的本地主机)工作正常,但在登录Java套接字编程:关闭套接字后连接重置?,java,sockets,tcp,Java,Sockets,Tcp,我目前正在编写一个简单的TCP聊天客户端-服务器应用程序,它可以与套接字一起工作。客户机连接到服务器,一旦被接受,就会创建一个新的工作线程来侦听客户机输入。连接到服务器(端口8818处的本地主机)工作正常,但在登录后,一旦工作线程开始侦听更多客户端输入,就会抛出java.net.SocketException:Connection reset(请参阅下面的堆栈跟踪)。我知道,此异常的一个可能来源可能是服务器或客户端未正确或强制关闭的套接字。因此,我的假设是,我没有正确处理客户端套接字的关闭,这会
后,一旦工作线程开始侦听更多客户端输入,就会抛出java.net.SocketException:Connection reset
(请参阅下面的堆栈跟踪)。我知道,此异常的一个可能来源可能是服务器或客户端未正确或强制关闭的套接字。因此,我的假设是,我没有正确处理客户端套接字的关闭,这会导致连接重置。我希望达到的目标是: 工作者侦听客户端输入,只要该输入不为null,就会处理请求(例如,简单登录),否则,套接字将关闭(请参阅下面的代码摘录)。我的客户端从服务器收到一条“Login Successful”(登录成功)消息,指示我的
handleLogin()
函数工作,但在没有从客户端收到更多输入后,服务器似乎只是复位,即使在while循环后发出clientSocket.close()
Server.java
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(serverPort);
while (true) {
// Accept connection(s) from new chat client(s)
System.out.println("SERVER: WAITING TO ACCEPT CLIENT CONNECTIONS ...");
Socket clientSocket = serverSocket.accept();
System.out.println("SERVER: CONNECTION ACCEPTED FROM: " + clientSocket);
// Process client request in separate Thread
WorkerThread worker = new WorkerThread(this, clientSocket);
workerList.add(worker);
worker.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
handleClientSocket();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void handleLogin(OutputStream outputStream, String[] tokens) throws IOException {
if (tokens.length != 3) {
outputStream.write("LOGIN FAILED!\n".getBytes());
return;
}
// Extract username and password from user input
String username = tokens[1];
String password = tokens[2];
if (username.equals("anna") && password.equals("anna")) {
outputStream.write("Login successful!\n".getBytes());
} else {
outputStream.write("Error logging in!\n".getBytes());
}
}
private void handleClientSocket() throws IOException, InterruptedException {
InputStream inputStream = clientSocket.getInputStream();
this.outputStream = clientSocket.getOutputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
// THIS IS WHERE THE EXCEPTION OCCURS AFTER CLIENT HAS LOGGED IN SUCCESSFULLY
while ((line = bufferedReader.readLine()) != null) {
String[] tokens = StringUtils.split(line);
if (tokens.length > 0 && tokens != null) {
String command = tokens[0];
// Evaluate the entered command and handle the request accordingly
if ("login".equalsIgnoreCase(command)) {
handleLogin(outputStream, tokens);
}
// process other commands ...
}
}
clientSocket.close(); // POSSIBLY WORNG WAY OF CLOSING THE CLIENT SOCKET?
}
import java.io.*;
import java.net.Socket;
public class Client {
private final String serverName;
private final int serverPort;
private Socket mySocket;
private OutputStream serverOut;
private InputStream serverIn;
public Client(String serverName, int serverPort) {
this.serverName = serverName;
this.serverPort = serverPort;
}
private boolean connect() {
try {
mySocket = new Socket(serverName, serverPort);
serverOut = mySocket.getOutputStream();
serverIn = mySocket.getInputStream();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
private void login(String username, String password) throws IOException {
String command = "login " + username + " " + password + "\n";
serverOut.write(command.getBytes());
}
public static void main(String[] args) throws IOException {
Client client = new Client("localhost", 8818);
if (client.connect()) {
System.out.println("Connection successful!");
client.login("anna", "anna");
} else {
System.err.println("Connection failed ...");
}
}
}
WorkerThread.java
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(serverPort);
while (true) {
// Accept connection(s) from new chat client(s)
System.out.println("SERVER: WAITING TO ACCEPT CLIENT CONNECTIONS ...");
Socket clientSocket = serverSocket.accept();
System.out.println("SERVER: CONNECTION ACCEPTED FROM: " + clientSocket);
// Process client request in separate Thread
WorkerThread worker = new WorkerThread(this, clientSocket);
workerList.add(worker);
worker.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
handleClientSocket();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void handleLogin(OutputStream outputStream, String[] tokens) throws IOException {
if (tokens.length != 3) {
outputStream.write("LOGIN FAILED!\n".getBytes());
return;
}
// Extract username and password from user input
String username = tokens[1];
String password = tokens[2];
if (username.equals("anna") && password.equals("anna")) {
outputStream.write("Login successful!\n".getBytes());
} else {
outputStream.write("Error logging in!\n".getBytes());
}
}
private void handleClientSocket() throws IOException, InterruptedException {
InputStream inputStream = clientSocket.getInputStream();
this.outputStream = clientSocket.getOutputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
// THIS IS WHERE THE EXCEPTION OCCURS AFTER CLIENT HAS LOGGED IN SUCCESSFULLY
while ((line = bufferedReader.readLine()) != null) {
String[] tokens = StringUtils.split(line);
if (tokens.length > 0 && tokens != null) {
String command = tokens[0];
// Evaluate the entered command and handle the request accordingly
if ("login".equalsIgnoreCase(command)) {
handleLogin(outputStream, tokens);
}
// process other commands ...
}
}
clientSocket.close(); // POSSIBLY WORNG WAY OF CLOSING THE CLIENT SOCKET?
}
import java.io.*;
import java.net.Socket;
public class Client {
private final String serverName;
private final int serverPort;
private Socket mySocket;
private OutputStream serverOut;
private InputStream serverIn;
public Client(String serverName, int serverPort) {
this.serverName = serverName;
this.serverPort = serverPort;
}
private boolean connect() {
try {
mySocket = new Socket(serverName, serverPort);
serverOut = mySocket.getOutputStream();
serverIn = mySocket.getInputStream();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
private void login(String username, String password) throws IOException {
String command = "login " + username + " " + password + "\n";
serverOut.write(command.getBytes());
}
public static void main(String[] args) throws IOException {
Client client = new Client("localhost", 8818);
if (client.connect()) {
System.out.println("Connection successful!");
client.login("anna", "anna");
} else {
System.err.println("Connection failed ...");
}
}
}
Client.java
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(serverPort);
while (true) {
// Accept connection(s) from new chat client(s)
System.out.println("SERVER: WAITING TO ACCEPT CLIENT CONNECTIONS ...");
Socket clientSocket = serverSocket.accept();
System.out.println("SERVER: CONNECTION ACCEPTED FROM: " + clientSocket);
// Process client request in separate Thread
WorkerThread worker = new WorkerThread(this, clientSocket);
workerList.add(worker);
worker.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
handleClientSocket();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void handleLogin(OutputStream outputStream, String[] tokens) throws IOException {
if (tokens.length != 3) {
outputStream.write("LOGIN FAILED!\n".getBytes());
return;
}
// Extract username and password from user input
String username = tokens[1];
String password = tokens[2];
if (username.equals("anna") && password.equals("anna")) {
outputStream.write("Login successful!\n".getBytes());
} else {
outputStream.write("Error logging in!\n".getBytes());
}
}
private void handleClientSocket() throws IOException, InterruptedException {
InputStream inputStream = clientSocket.getInputStream();
this.outputStream = clientSocket.getOutputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
// THIS IS WHERE THE EXCEPTION OCCURS AFTER CLIENT HAS LOGGED IN SUCCESSFULLY
while ((line = bufferedReader.readLine()) != null) {
String[] tokens = StringUtils.split(line);
if (tokens.length > 0 && tokens != null) {
String command = tokens[0];
// Evaluate the entered command and handle the request accordingly
if ("login".equalsIgnoreCase(command)) {
handleLogin(outputStream, tokens);
}
// process other commands ...
}
}
clientSocket.close(); // POSSIBLY WORNG WAY OF CLOSING THE CLIENT SOCKET?
}
import java.io.*;
import java.net.Socket;
public class Client {
private final String serverName;
private final int serverPort;
private Socket mySocket;
private OutputStream serverOut;
private InputStream serverIn;
public Client(String serverName, int serverPort) {
this.serverName = serverName;
this.serverPort = serverPort;
}
private boolean connect() {
try {
mySocket = new Socket(serverName, serverPort);
serverOut = mySocket.getOutputStream();
serverIn = mySocket.getInputStream();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
private void login(String username, String password) throws IOException {
String command = "login " + username + " " + password + "\n";
serverOut.write(command.getBytes());
}
public static void main(String[] args) throws IOException {
Client client = new Client("localhost", 8818);
if (client.connect()) {
System.out.println("Connection successful!");
client.login("anna", "anna");
} else {
System.err.println("Connection failed ...");
}
}
}
堆栈跟踪
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:189)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at WorkerThread.handleClientSocket(WorkerThread.java:70)
at WorkerThread.run(WorkerThread.java:45)
当我用PUTTY测试我的服务器时(即通过连接到本地主机,然后在PUTTY的终端中发出命令),一切正常。我对socket编程还是相当陌生的,所以这里可能也有一个逻辑缺陷。任何帮助将非常感谢,因为我真的很想继续这个项目。
提前谢谢 出现此异常的原因是,您在连接服务器后终止了客户端,但服务器仍从流中读取某些内容。出现异常。以下是我测试的代码:
while (inputStream.available() != 0) {
line = bufferedReader.readLine();
String[] tokens = StringUtils.split(line);
if (tokens.length > 0 && tokens != null) {
String command = tokens[0];
// Evaluate the entered command and handle the request accordingly
if ("login".equalsIgnoreCase(command)) {
handleLogin(outputStream, tokens);
}
// process other commands ...
}
}
更改while循环中的条件,以检查inputstream是否仍然可以读取。我认为客户端正在关闭连接,我没有看到任何循环在登录后等待更多信息。工作正常,非常感谢!)不幸的是,我不能给你一个适当的投票,但我接受了你的答案!那很好。我不赞成投票,所以没关系。