Существует клиент-серверное приложения, на серверной(мультипотоковой) части я пытаюсь реализовать синглтон:
public class Server {
private static Server server = new Server();
public static Server getInstance() {
return server;
}
private ServerSocket myServerSocket = null;
private boolean ServerOn = true;
private int clientAmount = 0; //Количество клиентов
private Server() {
try {
myServerSocket = new ServerSocket(2222);
System.out.println("Подключение сервера прошло успешно.");
Class.forName("by.markovsky.database.DatabaseConnection");
}
catch(ClassNotFoundException exp)
{
System.err.print("Не найден класс DatabaseConnection.");
System.exit(-1);
}
catch(IOException ioe) {
System.err.println("Невозможно создать сервер-сокет на порте " + 2222 + ". Завершение работы...");
System.exit(-1);
}
while(ServerOn) {
try {
myServerSocket.setSoTimeout(10);
Socket clientSocket = myServerSocket.accept();
System.out.println("Общее количество подключённых клиентов: "+ ++clientAmount);
ClientServiceThread cliThread = new ClientServiceThread(clientSocket);
cliThread.start();
}
catch(SocketTimeoutException ex){
}
catch(IOException ioe) {
System.out.println("Возникла ошибка подключения. Трассировка стека: ");
ioe.printStackTrace();
}
}
closeSocket();
}
//Отключение сервера
private void closeSocket(){
try {
myServerSocket.close();
System.out.println("Работа сервера остановлена.");
System.exit(1);
}
catch(Exception ioe) {
System.err.println("Возникла неожиданная ошибка сервера.");
System.exit(-1);
}
}
class ClientServiceThread extends Thread {
private Socket myClientSocket = null;
private boolean ClientThreadOn = true;
private ObjectOutputStream out = null;
private ObjectInputStream in = null;
private Package pack = null;
public ClientServiceThread() {
super();
}
ClientServiceThread(Socket s) {
myClientSocket = s;
}
//Новый поток
public void run() {
System.out.println("Адрес нового клиента: " + myClientSocket.getInetAddress().getHostName());
try {
out = new ObjectOutputStream(myClientSocket.getOutputStream());
in = new ObjectInputStream(myClientSocket.getInputStream());
while(ClientThreadOn) {
pack = (Package) in.readObject(); //Получение пакета
System.out.println("Команда клиента: " + pack.getCommand());
//Сервер отключен?
if(!ServerOn) { //ВОТ ТУТ КОД ПЕРЕСТАЕТ ВЫПОЛНЯТЬСЯ
System.out.print("Сервер отключен.");
pack.setAnswer("Сервер отключен.");
out.writeObject(pack);
out.flush();
out.reset();
ClientThreadOn = false;
}
}
}
catch(Exception e) {
e.printStackTrace();
}
finally {
try {
out.close();
in.close();
myClientSocket.close();
System.out.println("...Клиент отключен");
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
}
public static void main(String[] args){
}
}
Подключение клиента проходит хорошо, однако после отправления сообщения клиент зависает, причём объект отправляется клиентом и получается сервером и при достижении блока if с переменной внешнего класса код перестаёт выполняться(хотя до этого данная переменная уже использовалась внешним классом). Далее, я переделал код для проверки и он заработал.
public class Server {
private static Server server;
public static Server getInstance() {
return server=new Server(); //ДОБАВИЛ ЭТО
}
private ServerSocket myServerSocket = null;
private boolean ServerOn = true;
private int clientAmount = 0; //Количество клиентов
private Server() {
try {
myServerSocket = new ServerSocket(2222);
System.out.println("Подключение сервера прошло успешно.");
Class.forName("by.markovsky.database.DatabaseConnection");
}
catch(ClassNotFoundException exp)
{
System.err.print("Не найден класс DatabaseConnection.");
System.exit(-1);
}
catch(IOException ioe) {
System.err.println("Невозможно создать сервер-сокет на порте " + 2222 + ". Завершение работы...");
System.exit(-1);
}
while(ServerOn) {
try {
myServerSocket.setSoTimeout(10);
Socket clientSocket = myServerSocket.accept();
System.out.println("Общее количество подключённых клиентов: "+ ++clientAmount);
ClientServiceThread cliThread = new ClientServiceThread(clientSocket);
cliThread.start();
}
catch(SocketTimeoutException ex){
}
catch(IOException ioe) {
System.out.println("Возникла ошибка подключения. Трассировка стека: ");
ioe.printStackTrace();
}
}
closeSocket();
}
//Отключение сервера
private void closeSocket(){
try {
myServerSocket.close();
System.out.println("Работа сервера остановлена.");
System.exit(1);
}
catch(Exception ioe) {
System.err.println("Возникла неожиданная ошибка сервера.");
System.exit(-1);
}
}
class ClientServiceThread extends Thread {
private Socket myClientSocket = null;
private boolean ClientThreadOn = true;
private ObjectOutputStream out = null;
private ObjectInputStream in = null;
private Package pack = null;
public ClientServiceThread() {
super();
}
ClientServiceThread(Socket s) {
myClientSocket = s;
}
//Новый поток
public void run() {
System.out.println("Адрес нового клиента: " + myClientSocket.getInetAddress().getHostName());
try {
out = new ObjectOutputStream(myClientSocket.getOutputStream());
in = new ObjectInputStream(myClientSocket.getInputStream());
while(ClientThreadOn) {
pack = (Package) in.readObject(); //Получение пакета
System.out.println("Команда клиента: " + pack.getCommand());
//Сервер отключен?
if(!ServerOn) { //ВОТ ТУТ КОД ПЕРЕСТАЕТ ВЫПОЛНЯТЬСЯ
System.out.print("Сервер отключен.");
pack.setAnswer("Сервер отключен.");
out.writeObject(pack);
out.flush();
out.reset();
ClientThreadOn = false;
}
}
}
catch(Exception e) {
e.printStackTrace();
}
finally {
try {
out.close();
in.close();
myClientSocket.close();
System.out.println("...Клиент отключен");
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
}
public static void main(String[] args){
Server.getInstance();
}
}
Также пробовал заменить private модификатор на protected и код тоже заработал(при этом ide предлагало всё же заменить на private) Вопрос: Почему в первом случае код перестаёт выполняться при достижении private переменной внешнего класса, а во втором всё срабатывает отлично? P.S.: Без синглтона также всё работает отлично
Виртуальный выделенный сервер (VDS) становится отличным выбором
мне надо получить dom документа , который я получаю в виде inputStream есть ли такая возможность ? пробовал
Есть поле String, которое может быть nullИ вот если оно null, то в ответе в json этот null не показывается