简体   繁体   English

客户端-服务器双向通讯

[英]Client-server two way communication

I wrote simple client serwer, but unfortunately, I did it so chaotic and poorly that I decided to write everything from scratch. 我编写了简单的客户服务程序,但不幸的是,我做得如此混乱且糟糕,以至于我决定从头开始编写所有内容。 I want to write to communicate in both directions with the ability to disconnect and connect a new client. 我想编写双向通信,并具有断开和连接新客户端的能力。 It means the client or the server sends a message and an appropriate one reads it. 这意味着客户端或服务器发送一条消息,并且适当的人可以读取它。 At the beginning all works but when i want to close client i get two errors: 一开始一切正常,但是当我想关闭客户端时,出现两个错误:

java.net.SocketException: Socket closed readSocketData()
java.net.SocketException: Socket closedwriteData(String data)

Of course I understand what those errors means , but I do not understand why they show up because i have a while loop in which i check if the client is connected. 当然,我理解这些错误的含义,但我不明白为什么会出现这些错误,因为我有一个while循环,在其中检查客户端是否已连接。 Later when i try to connect a new client everything is falling apart. 稍后,当我尝试连接新客户端时,一切都崩溃了。 I wrote 3 classes client, server and communication. 我编写了3类客户端,服务器和通信类。 Client and server inherits from communication (methods for opening and reading data streams). 客户端和服务器从通信继承(用于打开和读取数据流的方法)。 It all looks like that: 一切看起来像这样:

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)

Of course I understand what those errors means 我当然明白那些错误是什么意思

They mean you closed the socket and continued to use it. 它们表示您已关闭插座并继续使用它。

but I do not understand why they show up because i have a while loop in which i check if the client is connected. 但是我不明白为什么它们会出现,因为我有一个while循环,我在其中检查客户端是否已连接。

No you don't. 不,你不会。 You have a while loop in which you check if the client socket is still open, which isn't the same thing at all ... but in any case that doesn't prevent you from using a closed socket inside the loop, for example after you close it in closeConnection() , whose return value being back to front from what it should be is doubtless causing confusion, and which is called by two threads as far as I can tell. 您有一个while循环,您可以在其中检查客户端套接字是否仍处于打开状态,这根本不是一回事……但是在任何情况下,这都不会阻止您在循环内部使用封闭的套接字在closeConnection()关闭它之后,其返回值无疑应该从后面回到最前面,这无疑会引起混乱,据我所知,这由两个线程调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM