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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Возврат по условию-2, на всякий случай в новый топик... 
:(
    Опции темы
Alone
Дата 19.8.2004, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 11.5.2003
Где: Dnepropetrovsk, U A

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



По ходу дела возник еще вопрос:
а как отловить таймаут в ожидании???
wait(timeout) генерит ексепшны
# IllegalArgumentException
# IllegalMonitorStateException
# InterruptedException
но это не туда... как быть? Чего я не учел?
как мне определить, что было прерывание по таймауту???


--------------------
web developer/telecommunication specialist.
mailto: [email protected]
ICQ#28442924

PM MAIL WWW ICQ   Вверх
AntonSaburov
Дата 19.8.2004, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

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



А почему должно быть прерывание по таймауту. Если просто истекло время - программа продолжит свое исполнение. И все. Т.е. отсутствие эксепшенов и есть признак, что таймаут кончился.

Если ошибаюсь - поправьте.
PM MAIL WWW ICQ   Вверх
Alone
Дата 19.8.2004, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 11.5.2003
Где: Dnepropetrovsk, U A

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



Скажем так: из объекта А я отправил запрос объекту Б, который работает с сокетом. Он в свою очередь удачно отправил запрос на сервер. Но я со стороны А ставлю условие, что ответ должен прийти не позднее чем через 3 сек. и ставлю таймаут.
Если нужный мне тип ответа придет - объект Б нотифицирует моего ожидающего А и он продолжит работу. Но если вылет по таймауту - я должен сигнализировать об ошибке.
Вот такая ситуация...
Я кстати уже нашел решение. smile.gif

Объект А:

boolean a=false;
lock.wait(timeOut)
if(!a) {
timeout error
}

Объект Б:

if(received){
A.a=true;
lock.notify()
}

что то типа такого...


--------------------
web developer/telecommunication specialist.
mailto: [email protected]
ICQ#28442924

PM MAIL WWW ICQ   Вверх
Domestic Cat
Дата 19.8.2004, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



А лучсе всего использовать java.nio.* - он позволяет асинхронную работу с сокетами, что
гораздо эффективнее.


--------------------

PM   Вверх
LSD
Дата 19.8.2004, 23:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Alone решение правильное (я бы тоже так делал), только добавить синхронизацию и все.



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
redrick
Дата 20.8.2004, 03:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



я вот подобную вещь видел сделанной немного по-другому... завтра попробую раскопать сорс и сказать как именно, но идея в том, что вокруг объекта Б делается класс типа TimeoutSocket, а он в случае таймаута кидает ексепшн, который и ловится...


--------------------
Имею Мнение Хрен Оспоришь   
PM MAIL ICQ   Вверх
Alone
Дата 20.8.2004, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 11.5.2003
Где: Dnepropetrovsk, U A

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



Цитата(LSD @ 19.8.2004, 23:04)
Alone решение правильное (я бы тоже так делал), только добавить синхронизацию и все.

Естественно с синхронизацией, я просто в примере не писал. wink.gif
Добавлено @ 09:57
Цитата(Domestic @ 19.8.2004, 21:34)
А лучсе всего использовать java.nio.* - он позволяет асинхронную работу с сокетами, что
гораздо эффективнее.

Эффективнее по сравнению с чем?


--------------------
web developer/telecommunication specialist.
mailto: [email protected]
ICQ#28442924

PM MAIL WWW ICQ   Вверх
Alone
Дата 20.8.2004, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 11.5.2003
Где: Dnepropetrovsk, U A

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



Цитата(redrick @ 20.8.2004, 03:58)
я вот подобную вещь видел сделанной немного по-другому... завтра попробую раскопать сорс и сказать как именно, но идея в том, что вокруг объекта Б делается класс типа TimeoutSocket, а он в случае таймаута кидает ексепшн, который и ловится...

Тут хитрость - в работе с сокетами...
в данном случае с сокетом одновременно работают несколько объектов. каждый из них отправляет через сокет запросы. Когда что-то приходит на сокет - оно парсится и выполняется соответствующие вызова каких либо методов. вот тут никто никакой гарантии на временные интервалы дать не сможет. Пример
1. Объект "А" послал запрос сокету (Объект "Б")
2. Объект "С" тоже послал свой запрос "Б"
"Б" взаимодействует с сервером
3. в "Б" возвращается ответ для "А" , который передается по сети 20сек
4. И о каком таймауте для сокета может идти речь smile.gif
Сокет "работает" честно... а вот данные пришли позднее чем были нужны smile.gif
Если сокет по какой либо "технической" причине не сможет принять / отправить данные , он сообщит через своего обработчика ошибок, и это будет ошибка сети wink.gif

Хух... заговорился... smile.gif


--------------------
web developer/telecommunication specialist.
mailto: [email protected]
ICQ#28442924

PM MAIL WWW ICQ   Вверх
Domestic Cat
Дата 20.8.2004, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Цитата(Alone @ 20.8.2004, 01:44)
Эффективнее по сравнению с чем?


По сравнению с синхронным IO, то есть java.net.*, java.io.*.


--------------------

PM   Вверх
Alone
Дата 20.8.2004, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 11.5.2003
Где: Dnepropetrovsk, U A

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



Гм... я почему то думал, что как раз наоборот, синхронные лучше/эффективнее асинхронных...
Где я неправ?


--------------------
web developer/telecommunication specialist.
mailto: [email protected]
ICQ#28442924

PM MAIL WWW ICQ   Вверх
Domestic Cat
Дата 20.8.2004, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Синхронный IO означает, что поток должен ждать завершения действия
(например, подключения клиента). В это время ничего другого поток делать не может.
Значит, нужно несколько потоков.
В асинхронном такие операции не являются блокирующими, и поток может одновременно
(почти smile.gif ) ждать клиента, работать с 10 другими клиентами и пр.
Если нужен всего один поток, то это естественно, эффективнее, чем несколько потоков.


--------------------

PM   Вверх
redrick
Дата 20.8.2004, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



вот по этому поводу

Цитата

и поток может одновременно
(почти  ) ждать клиента, работать с 10 другими клиентами и пр.


интересна такая вещь : это реализуется внутри самого потока ? т. е. это ведь возможно только если один объект знает о нескольких потоках, которые он обслуживает (скажем сокет соединяется с несколькими серверами). Я по роду деятельности сталкивался с асинхронным API в .NET - там есть beginInvoke(), который отправляет запрос на сервер и выдает вам хендел hr, вы делаете что хотите и когда закончили и вам понадобились данные вызываете endInvoke(hr), который либо выдает данные, либо блокируется до тоговремени, когда они будут. Ну и т. п.

Вобщем есть ли в Java нечто подобное и почему ?


--------------------
Имею Мнение Хрен Оспоришь   
PM MAIL ICQ   Вверх
Domestic Cat
Дата 20.8.2004, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Ну я просто для примера приведу код асинхронного сервера (из J. Hart, Java 1.4 Core Platform Update):
Server2 может делать accept, чтение и запись в несколько сокетов в одном потоке.
Код

import java.nio.channels.*;
import java.nio.*;
import java.io.*;
import java.net.*;
import java.util.*;

public class Server2 implements MessageProtocol {

 public static void main(String[] args) {
   MessageReceiver messageReceiver = new MessageReceiver();
   MessageSender messageSender = new MessageSender();

   try {
     int id = 0;

     Selector selector = Selector.open();

     ServerSocketChannel ssc = ServerSocketChannel.open();
     ssc.configureBlocking(false);

     ServerSocket server = ssc.socket();
     server.bind(new InetSocketAddress(DEFAULT_PORT));

     ssc.register(selector, SelectionKey.OP_ACCEPT);
     int a;

     while (true) {
       a = selector.select();

       if (a > 0) {
         try {
           Set keys = selector.selectedKeys();

           Iterator i = keys.iterator();

           while (i.hasNext()) {

             SelectionKey selectedChannelKey =
               (SelectionKey) i.next();

             i.remove();

             int purpose = selectedChannelKey.interestOps();

             if ((purpose & SelectionKey.OP_ACCEPT) > 0) {

               ServerSocketChannel selectedChannel =
                 (ServerSocketChannel) selectedChannelKey.channel();
               SocketChannel sock = selectedChannel.accept();
               sock.configureBlocking(false);

               sock.register(selector, SelectionKey.OP_READ);

             } else if ((purpose & SelectionKey.OP_READ) > 0) {
               
               SocketChannel sock =
                 (SocketChannel) selectedChannelKey.channel();
               messageReceiver.receive(sock);

               sock.register(selector, SelectionKey.OP_WRITE);

             } else if ((purpose & SelectionKey.OP_WRITE) > 0) {
               
               SocketChannel sock =
                 (SocketChannel) selectedChannelKey.channel();

               messageSender.send(sock, id++, "TEXT",
                                  "Message received and understood");

               sock.close();

             }
           }
         } catch (Exception e) {
           System.out.println(e.getMessage());
           e.printStackTrace();
         }
       }
     }
   } catch (Exception e) {
     System.out.println(e.getMessage());
     e.printStackTrace();
   }
 }
}



Код

public class Client implements MessageProtocol {

 public static void main(String[] args) {
   if (args.length < 1) {
     System.exit(1);
   }

   try {
     SocketChannel sock = SocketChannel.open();
     sock.connect(new InetSocketAddress(args[0], DEFAULT_PORT));

     new  MessageSender().send(sock, 0, "TEXT",
                              "testing, testing, 1, 2, 3");
     new MessageReceiver().receive(sock);
   } catch (Exception e) {
     System.out.println(e.getMessage());
     e.printStackTrace();
   }
 }
}


Код

public interface MessageProtocol extends ByteSizes {
 public static final int MESSAGE_ID_LENGTH     = 1 * INT_SIZE;
 public static final int MESSAGE_TYPE_LENGTH   = 4 * CHAR_SIZE;
 public static final int MESSAGE_LENGTH_LENGTH = 1 * LONG_SIZE;
 public static final int DEFAULT_PORT          = 2000;
}



Конкретная имплементация MessageSender и MessageReceiver не важна, но если нужно, могу и их запостить
Добавлено @ 16:56
Код

public interface ByteSizes {
 public static final int BYTE_SIZE   = 1;
 public static final int CHAR_SIZE   = 2;
 public static final int SHORT_SIZE  = 2;
 public static final int INT_SIZE    = 4;
 public static final int FLOAT_SIZE  = 4;
 public static final int LONG_SIZE   = 8;
 public static final int DOUBLE_SIZE = 8;
}


Код

import java.nio.channels.*;
import java.nio.*;
import java.io.*;

public class MessageReceiver implements MessageProtocol {

 public void receive(ScatteringByteChannel in) throws IOException {
   ByteBuffer messageIdBytes = ByteBuffer.allocate(MESSAGE_ID_LENGTH);
   ByteBuffer messageTypeBytes = ByteBuffer.allocate(MESSAGE_TYPE_LENGTH);
   ByteBuffer messageLengthBytes = ByteBuffer.allocate(MESSAGE_LENGTH_LENGTH);

   in.read(new ByteBuffer[] {messageIdBytes, messageTypeBytes, messageLengthBytes});

   messageIdBytes.rewind();
   messageTypeBytes.rewind();
   messageLengthBytes.rewind();
   
int messageId      = messageIdBytes.asIntBuffer().get();
    String messageType = messageTypeBytes.asCharBuffer().toString();
    long messageLength = messageLengthBytes.asLongBuffer().get();

   ByteBuffer messageBytes = ByteBuffer.allocate((int) messageLength
                                                 * CHAR_SIZE);
   in.read(messageBytes);
   messageBytes.rewind();
   String message = messageBytes.asCharBuffer().toString();

   System.out.println("Msg: " + messageId);
   System.out.println("Type: " + messageType);
   System.out.println(message);
 }

 public static void main(String[] args) {
   if (args.length < 1) {
     System.exit(1);
   }

   try {
     FileChannel fc = new FileInputStream(args[0]).getChannel();

     new MessageReceiver().receive(fc);

   } catch (Exception e) {
     System.out.println(e.getMessage());
     e.printStackTrace();
   }
 }
}


Код

import java.nio.channels.*;
import java.nio.*;
import java.io.*;

public class MessageSender implements MessageProtocol {

 public void send(GatheringByteChannel out, int messageId,String messageType,String message) throws IOException {
   
ByteBuffer messageIdBytes = ByteBuffer.allocate(MESSAGE_ID_LENGTH);
    ByteBuffer messageTypeBytes = ByteBuffer.allocate(MESSAGE_TYPE_LENGTH);
    ByteBuffer messageLengthBytes = ByteBuffer.allocate(MESSAGE_LENGTH_LENGTH);
    ByteBuffer messageBytes = ByteBuffer.allocate(message.length() * CHAR_SIZE);
   
messageIdBytes.asIntBuffer().put(messageId);
    messageTypeBytes.asCharBuffer().put(messageType);
    messageLengthBytes.asLongBuffer().put((long) message.length());
    messageBytes.asCharBuffer().put(message);

    out.write(new ByteBuffer[] {messageIdBytes, messageTypeBytes, messageLengthBytes, messageBytes});
 
}

 public static void main(String[] args) {
   if (args.length < 1) {
     System.exit(1);
   }

   try {
     FileChannel fc = new FileOutputStream(args[0]).getChannel();
     new MessageSender().send(fc, 0, "TEXT", "hello world");
   } catch (Exception e) {
     System.out.println(e.getMessage());
     e.printStackTrace();
   }
 }
}




Это сообщение отредактировал(а) Domestic Cat - 20.8.2004, 16:52


--------------------

PM   Вверх
redrick
Дата 20.8.2004, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



спасибо большое за примеры (по хорошему сам конешно лазить бы должен =) ) -
прояснилось


--------------------
Имею Мнение Хрен Оспоришь   
PM MAIL ICQ   Вверх
Domestic Cat
Дата 20.8.2004, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Нема за що, как говорят у нас в Канадi smile.gif


--------------------

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

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

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


 




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


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

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