2013-11-10 2 views
1

Я пытаюсь общаться через сокеты с помощью TCP. Данные, которые необходимо отправить, представляют собой чертеж, пока он нарисован. Таким образом, вариант должен был бы отправить все точки или только фигуры (серии точек).Связь Java TCP через Socket

Поскольку было бы неплохо, если бы оно было нарисовано мгновенно, отправные точки выглядели лучше. Это только для местного использования, поэтому много данных не должно быть проблемой. Теперь проблема, с которой я сталкиваюсь, - это понять, как именно работает сокет. В настоящее время мой код выглядит следующим образом:

while(true){ 

     try { 
      Thread.sleep(10); 
     } 
     catch (InterruptedException e) {} 

     switch(connectionStatus){ 
     case CONNECTED: 
      if(isHost){ 
       try { 
        oos.writeObject(myObject); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      }else{ 
       try { 
        myObject = (myObjectType) ois.readObject(); 
        mainFrame.repaint(); 
       } catch (ClassNotFoundException e) { 
        e.printStackTrace(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      break; 
     } 
} 

Но, разумеется, это кажется довольно неэффективного, как это работает постоянно. Есть ли способ написать только ObjectOutputStream (oos), когда есть новые данные? Я думаю, что читать, что вы должны опросить. Чтение также очищает ObjectOutputStream?

Редактировать

Чтобы было ясно: я хочу, чтобы отправить несколько Point -Объекты через сокет. Поэтому каждый раз, когда добавляется Point, например, сервер, он должен отправить эту точку клиенту.

Теперь, что мне нужно, чтобы положить внутри oos.writeObject()? Единственный Point, или List от Point s? И как они извлекаются из ois.readObject()?

Я немного смущен, потому что запись в ObjectOutputStream может быть быстрой или медленной. Se, читающий ObjectInputStream - то, как я его вижу - может вызвать или вызвать большую задержку (если он считывает значение каждые ~ 15 мс, а точки добавляются быстрее) или вызывает много отставания.

ответ

1

Есть ли способ написать только ObjectOutputStream (oos), когда есть новые данные?

Да. Всякий раз, когда пользователь рисует что-то, нажимайте данные вниз по ObjectInputStream.

Я думаю, что вы должны опросить, хотя.

Это неверно. Как правило, чтение из открытого потока является операцией блокировки : если вы пытаетесь что-то прочитать и там ничего нет, метод read будет просто блокироваться до тех пор, пока не будут доступны новые данные.

+0

Так что, если я правильно понять, например, когда новый 'Point' добавляется, я просто нажмите «Point» на ObjectOutputStream, используя 'oos.writeObject (новая точка (20, 20))'? Что произойдет, если несколько точек были записаны в 'oos', прежде чем получатель« прочитает »их? – jdepypere

+0

Предполагая, что вы правильно обрабатываете многопоточность (если в вашей программе есть многопоточность), тогда да, вы просто нажимаете объект вниз по потоку. Если было написано несколько точек (последовательно! Вы должны записывать объекты в поток последовательно, а не параллельно), они будут считаться последовательно после того, как приемник начнет их читать. В то же время данные будут накапливаться в буфере между отправителем и получателем; это реализовано стеком TCP/IP, и, как правило, вам не придется беспокоиться об этом. – Isaac

+0

Не уверен в части многопоточности ... Это только от одной «программы» к другой, поэтому я не думаю, что мне это нужно. Тем не менее я просто нажал «Point's» на ObjectOutputStream по желанию отправителя и использовал 'while (true)' -part сверху для чтения «ObjectInputStream» и, похоже, он работает! Хотя вместо использования «Точек» я сделал класс, предоставляющий начальную и конечную точки линии. Так что пока я улажен и, похоже, работает без лаг, спасибо! – jdepypere

0
  1. Для записи вам необходимо использовать технологию потоковой передачи и синхронизации, чтобы писать только тогда, когда доступны данные. Один поток уведомляет о том, что новые данные стали доступными, а другой - для ожидания и получения уведомления и продолжения выполнения, когда сообщается, что данные приходят;
  2. Чтение не очищает ObjectOutputStream. Фактически, вы можете использовать два потока для одновременной обработки входных и выходных потоков.
  3. Чтение объекта - синхронная операция, означающая, что ваш поток ожидает, пока объект не будет готов.
0

Я написал библиотеку (которую вы можете найти на мавена), который заберет некоторые сложности реализации многопоточности и синхронизации себя:

https://github.com/xtrinch/socket-live

Состоит из трех основных компонентов (которые впоследствии приводят в трех запущенных потоки):

SocketConnection.java: основной поток, бежит пользователь библиотеки, что позволяет убедиться, что соединение всегда открыто

SocketRead.java: прочитайте нить, которая постоянно пытается читать входящие сообщения, если какой-либо

SocketWrite.java: написать поток, который записывает какие-либо сообщения в очереди на запись в сокет

У вас также есть возможность отключить считанную нить , если вам это не нужно.

Библиотека будет убедиться, что соединение остается открытым в любое время, повторно на время закрыты, и это было проверено бой :)

Смежные вопросы