Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> socket.Close(), Как закрыть только один клиентский сокет 
V
    Опции темы
polakwilno
Дата 18.8.2008, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 14.8.2006

Репутация: нет
Всего: нет



Добрый день,

Ситуация такая:

Создаю Н потоков (в одной ява програме), и каждый из них конектится к тому-же серверу. Проблема в том, что кодга один из них вызывает Close() метод, закрывается соединение и у других клиентов (у всех оставшихся Н-1 потоков).

1. Почему? (какойто общий идентификатор или что?)
2. Как с этим боротся? (т.е. есть-ли возможность работы нескольких клиентов из одной программы? просто хотел написать эмулятор клиентов и протестить сервер...)
PM MAIL   Вверх
neiron
Дата 18.8.2008, 14:26 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 18.4.2006
Где: Краснодар

Репутация: нет
Всего: 4



У меня для тестирования сервака примерно такая же тулзень написана. Всё корректно работает. 
Ты бы хоть кусочек кода показал - где и что открывается, что в потоках делается, и как всё закрывается. 

PM MAIL   Вверх
polakwilno
Дата 18.8.2008, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 14.8.2006

Репутация: нет
Всего: нет



Ясненько...

Вечерком вкину код

Спасибо ;)
PM MAIL   Вверх
polakwilno
Дата 10.9.2008, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 14.8.2006

Репутация: нет
Всего: нет



Извиняюсь, был в отпуске )

Похоже я несовсем правильно описал ситуацию (или теперь по какимто причинам програма ведет себя по другому). Просто когда клиентов больше чем 3, иногда разрывается соединение раньше времени с некоторыми клиентами. 

Как все работает: после конекта к серверу клиент шлет строку "char(0x01)|ИМЯ". Сервер сохраняет ИМЯ и высылает клиенту строку "r", получив которую клиент закрывает свой сокет. Cервер, обнаружив разрыв соединения, выводит сообщение, что клиент с именем ИМЯ отсоеденился. Проблема в том, что если сделать, скажем 10 клиентов (лучше сразу 500 для 100% эфекта) то будет видно, что с некоторыми клиентами связь разрывается еще до того, как сервер сохранит имя этого клиента. Я уверен, что что-то не то с дисконектом, потомучто если ни одного клиента не закрывать, то ни одно из соединений не закрывается. Если-же все закрывать сразу после регистрации (после получения строки "r"), то некоторые соединения разрываются сами по себе (иначе сервер имел-бы имя этого клиента)

Вот сам код

Сервер

Main.java
Код

package testServer;

import java.io.IOException;
import java.net.ServerSocket;

public class Main {

    static ServerSocket serverSocket = null;
    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            serverSocket = new ServerSocket(6899);
            serverSocket.setSoTimeout(0);
            System.out.println(serverSocket.toString());
            
            while(true){
                try{ 
                 new Client(serverSocket.accept()).run();
                }
                catch(IOException e){
                 System.out.println(e.getMessage());
                }
            }
        } catch(IOException e){
            System.out.println("Server socket: " + e.getMessage());
        }
    }
}


Client.java
Код

package testServer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class Client extends Thread {
    
    private Socket clientSocket = null;
    private BufferedReader in = null;
    private PrintWriter out = null;
    
    private boolean hasName = false;
    private String player_name = "";
    
    public Client(Socket socket) {
        this.clientSocket = socket;
        
        //create I/O streams
        this.crateStreams();
        
        //start listening loop
        new Thread() {
            public void run(){
                String clientInput = "";
                try {
                    while ( (in != null) && (clientInput = in.readLine()) != null){
                        char first_char = clientInput.charAt(0);
                        if ((hasName) && (first_char != ' ')){
                            //something
                        } else if (first_char == (char)((int)0x01)) {  //register name
                            hasName = true;
                            player_name = clientInput.substring(2);
                            System.out.println(player_name + " connected");
                            
                            out.println("r");
                            out.flush();
                        }
                    }
                    //System.out.println(player_name + " disconnected");
                } catch(IOException e){
                    if (player_name == "") {
                        System.out.println("!!!!!!!!!! Client with no name disconnected !!!!!!!!!!");
                    } else {
                        System.out.println(player_name + " disconnected");
                    }
                };
            }
        }.start();
    }
    
    /**
     * Sets I/O streams for connected client
     */
    private void crateStreams() {
        //creating output stream
        try{
            out = new PrintWriter(clientSocket.getOutputStream(), true);
        }
        catch(IOException e){
         System.out.println("Error creating PrintWriter");
        }
        
        //creating input stream
        try{
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        }
        catch(IOException e){
         System.out.println("Error creating BufferedReader");
        }
    }
}



Клиент

Main.java
Код

package emulator;

public class Main {
    
    /**
     * Server host
     */
    private static String host = "127.0.0.1";
    
    /**
     * Server port
     */
    private static int port = 6899;
    
    /**
     * how much client threads to start
     */
    private static int clients = 9;
    
    /**
     * how much times clients will reconnect to server
     */
    private static int reconnects = 1;
    
    /**    
     * clients name prefix
     */
    private static String name_prefix = "Client";

    /**
     * @param args not used
     */
    public static void main(String[] args) {
        int i = 0;
        
        for (i=0; i<clients; i++) {
            new Client(host, port, reconnects, name_prefix + " " + i).start();
        }
    }

}



Client.java
Код

package emulator;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class Client extends Thread {
    
    private Socket         clientSocket = null;
    private PrintWriter    os           = null;
    private BufferedReader in           = null;
    
    private String host = "";
    private int    port = 0;
    private String name = "";
    private int reconnects = 0;
    
    private boolean accepted = false;
    
    public Client(String host, int port, int reconnects, String name) {
        this.host       = host;
        this.port       = port;
        this.name       = name;
        this.reconnects = reconnects;
    }
    
    public void run() {
        int i = 0;
        
        for (i=0; i<reconnects; i++) {
            try {
                clientSocket = new Socket(host, port);
                os = new PrintWriter(clientSocket.getOutputStream());
                in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                if ( (os == null) || (in == null) ) {
                 System.out.println("Can't create I/O buffer");
                 System.exit(1);
                } else {
                 setPlayerName(name);
                }
                
                String serverInput = "";
                while( (in != null ) && (accepted == false) && (serverInput = in.readLine()) != null) {
                 if(serverInput.charAt(0) == 'r') {   //registered
                        accepted = true;
                        System.out.println("client " + name + " accepted");
                    }
                }
                if (in == null) {
                 System.out.println("connection error");
                }
                accepted = false;
                System.out.println(name + " disconnected");
                clientSocket.close();
            } catch(IOException e){
                System.out.println("Socket error: " + e.getLocalizedMessage() + "; " + host + ":" + port);
            }
        }
        
        System.exit(4);
    }
    
    public void setPlayerName(String s){
        if (os != null) {
            os.println(((char)((int)0x01)) + "|" + s);
            os.flush();
            System.out.println("Name sent: " + s);
        }
    }
}



Вот пример того, что выводится:

Код

!!!!!!!!!! Client with no name disconnected !!!!!!!!!!
Client 136 disconnected
!!!!!!!!!! Client with no name disconnected !!!!!!!!!!
Client 64 disconnected


Если чтото плохо обьяснил - говорите, постараюсь уточнить.
PM MAIL   Вверх
ivg
Дата 10.9.2008, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


Профиль
Группа: Участник
Сообщений: 686
Регистрация: 8.2.2006
Где: Екатеринбург

Репутация: 3
Всего: 81



polakwilno, в последнем листинге удалите 62 строку:
Код
        System.exit(4);
 - это причина. Ну и до кучи поправьте код сервера: в классе Main замените 20 строку на 
Код
                 new Client(serverSocket.accept()).start();
; в классе Client метод run() сделайте методом класса Client. И this.crateStreams() вызывайте в run(), а не в конструкторе.

Это сообщение отредактировал(а) ivg - 10.9.2008, 22:19
PM MAIL   Вверх
polakwilno
Дата 13.9.2008, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 14.8.2006

Репутация: нет
Всего: нет



Цитата(ivg @ 10.9.2008,  22:18)
polakwilno, в последнем листинге удалите 62 строку:
Код
        System.exit(4);
 - это причина. Ну и до кучи поправьте код сервера: в классе Main замените 20 строку на 
Код
                 new Client(serverSocket.accept()).start();
; в классе Client метод run() сделайте методом класса Client. И this.crateStreams() вызывайте в run(), а не в конструкторе.

Эх... как это чаще всего и бывает, глупая ошибка...

Огромное спасибо, ivq
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Работа с сетью | Следующая тема »


 




[ Время генерации скрипта: 0.0500 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.