[英]Client-server two way communication
我編寫了簡單的客戶服務程序,但不幸的是,我做得如此混亂且糟糕,以至於我決定從頭開始編寫所有內容。 我想編寫雙向通信,並具有斷開和連接新客戶端的能力。 這意味着客戶端或服務器發送一條消息,並且適當的人可以讀取它。 一開始一切正常,但是當我想關閉客戶端時,出現兩個錯誤:
java.net.SocketException: Socket closed readSocketData()
java.net.SocketException: Socket closedwriteData(String data)
當然,我理解這些錯誤的含義,但我不明白為什么會出現這些錯誤,因為我有一個while循環,在其中檢查客戶端是否已連接。 稍后,當我嘗試連接新客戶端時,一切都崩潰了。 我編寫了3類客戶端,服務器和通信類。 客戶端和服務器從通信繼承(用於打開和讀取數據流的方法)。 一切看起來像這樣:
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;
}
}
java.net.SocketException: Socket closed readSocketData()
java.net.SocketException: Socket closed writeData(String data)
我當然明白那些錯誤是什么意思
它們表示您已關閉插座並繼續使用它。
但是我不明白為什么它們會出現,因為我有一個while循環,我在其中檢查客戶端是否已連接。
不,你不會。 您有一個while
循環,您可以在其中檢查客戶端套接字是否仍處於打開狀態,這根本不是一回事……但是在任何情況下,這都不會阻止您在循環內部使用封閉的套接字在closeConnection()
關閉它之后,其返回值無疑應該從后面回到最前面,這無疑會引起混亂,據我所知,這由兩個線程調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.