Java 客户机-服务器双向通信
我写了一个简单的客户端serwer,但不幸的是,我写得太混乱和糟糕,以至于我决定从头开始写。我想写的是双向通信,能够断开和连接新客户机。这意味着客户机或服务器发送一条消息,并由适当的人读取。开始时一切正常,但当我想关闭客户端时,我会出现两个错误:Java 客户机-服务器双向通信,java,sockets,client-server,serversocket,Java,Sockets,Client Server,Serversocket,我写了一个简单的客户端serwer,但不幸的是,我写得太混乱和糟糕,以至于我决定从头开始写。我想写的是双向通信,能够断开和连接新客户机。这意味着客户机或服务器发送一条消息,并由适当的人读取。开始时一切正常,但当我想关闭客户端时,我会出现两个错误: java.net.SocketException: Socket closed readSocketData() java.net.SocketException: Socket closedwriteData(String data) 当然,我理解
java.net.SocketException: Socket closed readSocketData()
java.net.SocketException: Socket closedwriteData(String data)
当然,我理解这些错误的含义,但我不理解它们为什么会出现,因为我有一个while循环,在这个循环中我检查客户机是否已连接。后来,当我尝试连接新客户机时,一切都崩溃了。
我编写了三个类:客户端、服务器和通信。客户端和服务器继承自通信(用于打开和读取数据流的方法)。一切看起来都是这样的:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends Communication{
ServerSocket serverSocket;
Socket listener;
boolean listenerLife;
public Server(int port) {
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
System.out.println(e);
}
}
public void startListener(){
while (true){
try {
listener = serverSocket.accept();
listenerLife = true;
} catch (IOException e) {
System.out.println(e);
}
openWriter(listener);
openReader(listener);
writeServerDataThread();
new Thread(new Runnable() {
@Override
public void run() {
readData();
}
}).start();
}
}
public void writeServerDataThread(){
openLocalReader();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
String data = readLocalData();
writeData(data);
}
}
}).start();
}
public void readData(){
while (listenerLife){
String data = readSocketData();
if("exit".equals(data) || data == null){
try {
listenerLife = false;
listener.close();
} catch (IOException e) {
System.out.println(e);
}
}
else {
System.out.println(data);
}
}
}
public void writeData(String data){
try {
writer.writeBytes(data + '\n');
writer.flush();
} catch (IOException e) {
System.out.println(e);
}
}
public static void main(String[] args) {
Server server = new Server(8080);
server.startListener();
}
}
import java.io.IOException;
import java.net.Socket;
public class Client extends Communication{
Socket clientSocket;
boolean clientLive;
public Client(String hostName, int port) {
try {
clientSocket = new Socket(hostName, port);
clientLive = true;
} catch (IOException e) {
System.out.println(e + "Client(String hostName, int port)");
}
}
public boolean closeConnection(String data){
if("exit".equals(data) || data == null){
try {
writeData("Zamykam klienta");
clientSocket.close();
clientLive = false;
return false;
} catch (IOException e) {
System.out.println(e + "closeConnection(String data)");
}
}
return true;
}
public void readClientData(){
new Thread(new Runnable() {
@Override
public synchronized void run() {
openLocalReader();
while (!clientSocket.isClosed()){
String data = readLocalData();
if(closeConnection(data)){
writeData(data);
}
}
}
}).start();
}
public void readServerDataThread(){
new Thread(new Runnable() {
@Override
public synchronized void run() {
while (!clientSocket.isClosed()){
String data = readSocketData();
if(closeConnection(data)){
System.out.println(data);
}
}
}
}).start();
}
public void writeData(String data){
try {
writer.writeBytes(data + '\n');
writer.flush();
} catch (IOException e) {
System.out.println(e + "writeData(String data)");
}
}
public static void main(String[] args) {
final Client client = new Client("localhost", 8080);
client.openReader(client.clientSocket);
client.openWriter(client.clientSocket);
client.readServerDataThread();
client.readClientData();
}
}
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class Communication {
BufferedReader reader;
BufferedReader localReader;
DataOutputStream writer;
public void openReader(Socket incomingSocket){
try {
reader = new BufferedReader(new InputStreamReader(incomingSocket.getInputStream()));
} catch (IOException e) {
System.out.println(e);
}
}
public void openWriter(Socket incomingSocket){
try {
writer = new DataOutputStream(incomingSocket.getOutputStream());
} catch (IOException e) {
System.out.println(e);
}
}
public void openLocalReader(){
localReader = new BufferedReader(new InputStreamReader(System.in));
}
public String readLocalData(){
String data = null;
try {
data = localReader.readLine();
} catch (IOException e) {
System.out.println(e + " readLocalData()");
}
return data;
}
public String readSocketData(){
String data = null;
try {
data = reader.readLine();
} catch (IOException e) {
System.out.println(e + " readSocketData()");
}
return data;
}
}
我当然理解这些错误的含义
他们的意思是你关上插座继续使用
但我不明白为什么会出现这些问题,因为我有一个while循环,在这个循环中我检查客户机是否已连接
不,你没有。您有一个
while
循环,在该循环中检查客户端套接字是否仍处于打开状态,这根本不是一回事。。。但是在任何情况下,这都不会阻止您在循环中使用闭合的套接字,例如在closeConnection()
中关闭它之后,它的返回值从前向后,这无疑会造成混乱,据我所知,这是由两个线程调用的。我不明白。我该怎么办?
java.net.SocketException: Socket closed readSocketData()
java.net.SocketException: Socket closed writeData(String data)