Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.09.2013, 12:06   #1
Mars2107
Пользователь
 
Аватар для Mars2107
 
Регистрация: 15.05.2008
Сообщений: 18
По умолчанию Пишу чат на UDP (помогите дописать)

Все набросал как нужно, отправляет куда нужно. Встал вопрос о проверки дохода дейтаграмм до получателя, если не дошла, то отсылаем запрос на повторную отправку. Думаю лучше всего сделать через TimeStamp проверку. Как с этим работать не знаю, помогите ребята

Делал проверку другим способом, отправкой сообщения об посылке и обратно что пришло сообщение, но это лишняя нагрузка на канал. Нужно через саму дейтаграмму.


_____
Удалил вложенный файл с заражённым EXE

модератор

Последний раз редактировалось Serge_Bliznykov; 19.09.2013 в 09:05.
Mars2107 вне форума Ответить с цитированием
Старый 18.09.2013, 20:21   #2
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

1. Зачем столько (четыре!) UDP сокета? хватает одного IdUDPServer (по секрету сервер и посылать умеет IdUDPServer1.Send(...)
2. два таймера и никчемный поток...
это не дописывать, переделайте все за мной
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 18.09.2013, 23:27   #3
Mars2107
Пользователь
 
Аватар для Mars2107
 
Регистрация: 15.05.2008
Сообщений: 18
По умолчанию убрал лишний мусор

Как вы и сказали убрал все лишнее. Все эти компоненты и код были моими тщетными попытками реализации проверки датаграмм.

У вас есть идеи как сделать оптимально проверку?

Чат1(исходник).zip

___________
я пересобрал архив, удалив из него заражённый Project1.exe
Лечите вирус (Virus.Win32.Induc.b) на своём компьютере!!

Модератор

Последний раз редактировалось Serge_Bliznykov; 19.09.2013 в 08:48.
Mars2107 вне форума Ответить с цитированием
Старый 19.09.2013, 06:09   #4
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

подтвердить приемку можно только ответным сообщением...
Опять exeшник упаковал в архив! на экзешник ругается антивирь (win32.Induc) и гасит весь архив, нормально не скачать! перезалей и полечи компутер свой
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 19.09.2013, 09:51   #5
Mars2107
Пользователь
 
Аватар для Mars2107
 
Регистрация: 15.05.2008
Сообщений: 18
По умолчанию

Благодарю за совет, сам его не заметил. Все почистил, удалил. Отчёт VT только все равно одна бяка осталась. Но серьезного в ней нету.

Ув. Slym могли бы вы взглянуть на мой исходный код (ниже прикреплен), где я сделал проверку прихода сообщений и сказать, так ли вы имели ввиду? И если можно обойтись без лишних подтверждений и нагрузки на канал, можно ли еще проще сделать, чтобы избежать этого: отправил запрос, что сообщение послал и ждешь обратного запроса что пришло сообщение.

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

Допустим: 1клиент(1к) отправил сообщение 2к и если второй клиент получил его то отправляет отчет 1к, если 2к ничего не получил, то не отправляет ничего и в этом случае 1к ждет отчета, но через n секунд понимая, что обратного запроса нет, выдает сообщение о недоставке.

Вроде всю мысль изложил, поправте если где ошибаюсь пжл.
Вложения
Тип файла: zip Чат2(исходник).zip (8.5 Кб, 22 просмотров)

Последний раз редактировалось Mars2107; 19.09.2013 в 09:53.
Mars2107 вне форума Ответить с цитированием
Старый 19.09.2013, 12:41   #6
alextrof94
Форумчанин
 
Регистрация: 16.03.2013
Сообщений: 599
По умолчанию

Секунды - слишком долго. Udp вроде посылает данные по частям по N байт (8 вроде), доставку и целостность каждого пакета надо проверять. Затем клиент эти пакеты должен собрать и обработать. Сам могу ошибаться.
Более того Udp может и вовсе не посылать клиенту пакеты, т.е. посылать их в пустоту и это тоже надо проверять теми же обратными сообщениями.
alextrof94$gmail.com
alextrof94 вне форума Ответить с цитированием
Старый 19.09.2013, 13:36   #7
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

я бы делал так.
1. Очередь сообщений:
можно обычной TStringList для начала, но доп вкусности там сложно хранить.
а хранить надо iport, IDсообщения (случайная величина при старте приложения потом +случайный x для каждого сообщения), таймаут подтверждения, само сообщение. так что сразу бадяжим record

псевдокод (дельфи под рукой нет)
Код:
type
TMessage=record
  ID:integer;
  PeerIP:string;
  PeerPort:word;
  TimeOut:integer;
  Data:string;
end;

PUDPMsg=^TUDPMsg;
TUDPMsg=packed record
  MsgType:word;
  ID:integer;
  Data:array[0..0] of byte;
end;

var RndID=random(maxint);

procedure SendMessage(PeerIP,PeerPort,Msg);
var Message:TMessage;
begin
Inc(RndID,1+random(32));
Messages.id:=RndID;
Messages.PeerIP:=PeerIP;
Messages.PeerPort:=PeerPort;
Messages.TimeOut:=3000;
Message.Data:=Msg;
Messages.add(Message);
end;

procedure TimerOnTimer;
var UDPMsg:PUDPMsg;
UDPMsgLength:integer;
begin
  for i:=0 to Messages.Count-1 do
  begin
    if(Messages[i].TimeOut<=0) then
    begin
      Messages.delete(i);
      Log.add('message delivery failed');
    end;
    //нужно сформировать посылку
    UDPMsgLength:=SizeOf(UDPMsg.MsgType)+SizeOf(UDPMsg.ID)+length(Message[i].Data);
    GetMem(UDPMsg,UDPMsgLength);
    UDPMsg.MsgType:=TypeMsgSend;
    UDPMsg.id:=Messages[i].id;
    move(UDPMsg.Data,Messages[i].Data,length(Messages[i].Data));


    Udp.Send(Messages[i].PeerIP,Messages[i].PeerPort,UDPMsg,UDPMsgLength);
    FreeMem(UDPMsg);
    dec(Messages[i].TimeOut,1000);
  end;
end;

procedure UDPOnRead;
var Msg:PUDPMsg;
UDPMsgLength:integer;
begin
  Msg:=ParsePacket(stream);//лень писать
  case Msg.TypeMsg of
    TypeMsgSend: Log.add('message '+Msg.Data);Udp.Send(PeerIP,PeerPort,TypeMsgConfirm+Msg.id);
    TypeMsgConfirm: Log.add('message delivered');Messages.DeleteMsgByID(Msg.id);
  end;
end;
заметь никаких потоков! UDP не блокирует (или я не нарывался?) сокет.
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 19.09.2013 в 13:40.
Slym вне форума Ответить с цитированием
Старый 19.09.2013, 14:32   #8
Mars2107
Пользователь
 
Аватар для Mars2107
 
Регистрация: 15.05.2008
Сообщений: 18
По умолчанию

Немногое я отсюда понял, но куда это все вставлять? (я не так давно занимаюсь программированием)

Код:
var RndID=random(maxint);
на это ругается, вместо "=" ставлю ":" все равно ругается.

Потом вставляю процедуру

Код:
procedure SendMessage(PeerIP,PeerPort,Msg);
тоже ругается а дальше просто ничего не понял. Если не затруднит, можете вставить это в pas файл который в моем примере.
Mars2107 вне форума Ответить с цитированием
Старый 19.09.2013, 20:15   #9
alextrof94
Форумчанин
 
Регистрация: 16.03.2013
Сообщений: 599
По умолчанию

Если недавно пишешь программы, зачем лезть в UDP? Юзай TCP и отправку строк, tcp все проверки сделает за тебя.
alextrof94$gmail.com
alextrof94 вне форума Ответить с цитированием
Старый 19.09.2013, 20:19   #10
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию как-то так

Держи...
как-то так
Вложения
Тип файла: zip Чат2(исходник).zip (3.9 Кб, 41 просмотров)
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Синхронизировать чат на Indy UDP, способы реализации. Mars2107 Помощь студентам 2 23.08.2013 20:58
программа чат на udp сокетах builder c++ 6 Konstantin_ua Помощь студентам 2 14.05.2013 08:46
Чат на UDP f3arnil Фриланс 5 04.02.2013 16:31
Чат на UDP ImmortalAlexSan Работа с сетью в Delphi 0 03.05.2010 13:08
помогите сделать программу - чат (Indy UDP) dr_Lev Помощь студентам 2 02.12.2007 14:49