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

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

Вернуться   Форум программистов > Клуб программистов > Обсуждение статей
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 11.08.2010, 12:10   #551
Ckomoroh
Я еще только учусь
Форумчанин
 
Аватар для Ckomoroh
 
Регистрация: 24.10.2009
Сообщений: 125
По умолчанию

Сервер:

Код:
procedure TForm1.TankTimerTimer(Sender: TObject);
var
   i,j:integer;
   len:byte;
   buf:array[0..6] of byte;
begin
if TankServer.Socket.ActiveConnections<>0 then
  begin
  for i:=1 to TankServer.Socket.ActiveConnections do
    begin
    len:=TankServer.Socket.ReceiveLength;
    if len<>0 then
      begin
      TankServer.Socket.ReceiveBuf(buf,len);
      chatmemo.Lines.Add('Получили '+inttostr(buf[0])+' '+inttostr(buf[1])+' '+inttostr(buf[2])+' '
                                                 +inttostr(buf[3])+' '+inttostr(buf[4])+' '+inttostr(buf[5])+' '+inttostr(buf[6])+' ');
      if buf[0]<>0 then
        begin
        if buf[0]=1 then  //Прислали номер
          if buf[1]=0 then //Если номер = 0
            begin
            j:=1;
            While TankMas[j].n<>0 do inc(j);
            buf[0]:=2;
            buf[1]:=j;
            buf[2]:=1;
            buf[3]:=1;
            TankServer.Socket.Connections[i].SendBuf(buf,bufd); 
            end;
        end;
      end;
    end;
  if updoTank=true then
    begin
      nomer;
      updoTank:=false;
    end;
  end;
end;
Код:
procedure TForm1.TankServerClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  upDoTank:=true;
end;
Код:
procedure TForm1.nomer;
var
  i:integer;
  buf:array[0..6] of byte;
begin
  buf[0]:=1;
  for i:=1 to TankServer.Socket.ActiveConnections do
    begin
    chatmemo.Lines.Add('Отправляем запрос клиенту №'+inttostr(i));
    TankServer.Socket.Connections[i-1].SendBuf(buf,bufd);
    end;
end;
Клиент:

Код:
procedure TForm1.TankClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  len:byte;
begin
  len:=TankClient.Socket.ReceiveLength;
  TankClient.Socket.ReceiveBuf(buf,len);
  if buf[0]<>0 then
    begin
    if buf[0]=1 then //Запрос номера
      begin
      bufo[0]:=1;
      bufo[1]:=player.n;
      TankClient.Socket.SendBuf(bufo,bufd);
      ChatMemo.Lines.Add('Отправляем номер');
      end;
    if buf[0]=2 then //Прислали номер
      begin
      player.n:=buf[1];
      player.x:=buf[2];
      player.y:=buf[3];
      ChatMemo.Lines.Add('Получены данные. Номер='+inttostr(player.n)+', Координаты '+inttostr(player.x)+':'+inttostr(player.y));
      end;
    end;
end;
При подключении сервер отправляет запрос на номер, клиент его получает, отправляет данные, но данные до сервера не доходят =(

Последний раз редактировалось Beermonza; 11.08.2010 в 16:37.
Ckomoroh вне форума Ответить с цитированием
Старый 11.08.2010, 16:33   #552
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Shouldercannon, длина пакета содержится в ServerSocket.Socket.ReceiveLength, присваивайте это некоторой переменной, затем переменную проверяйте на лимит.

Последовательность строго прописана. Что будет если в пакете первые два символа - числа, а сам он весит 1М ? ...сначала проверяйте на лимит пакета, вторым шагом - код команд, первые два символа. Затем соответствие длины пакета строгой команды. Не знаю как еще объяснить, может так:

1) Размер пакета меньше 2000 ?
Да: пропустить в шаг 2)
Нет: выполнить счет нарушения

2) Первые два символа числа ?
Да: пропустить в шаг 3)
Нет: выполнить счет нарушения

3) Есть ли команды с кодом, как были получены ?
Да: пропустить в шаг 4)
Нет: выполнить счет нарушения

4) Длина пакета команды соответствует длине по такому коду ?
Да: пропустить в обработку пакет
Нет: выполнить счет нарушения

Как только пользователь в короткий срок набрал штрафов до некоторого уровня, производите с ним действия.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 11.08.2010, 16:53   #553
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Ckomoroh, ошибка в обращении к каналу у сервера по номеру.

Код:
procedure TForm1.TankTimerTimer(Sender: TObject);
var
   i,j:integer;
   len:byte;
   buf:array[0..6] of byte;
begin
if TankServer.Socket.ActiveConnections<>0 then
  begin
  for i:=1 to TankServer.Socket.ActiveConnections do
    begin
    len:=TankServer.Socket.Connections[i-1].ReceiveLength;
    if len<>0 then
      begin
      TankServer.Socket.Connections[i-1].ReceiveBuf(buf,len);
      chatmemo.Lines.Add('Получили '+inttostr(buf[0])+' '+inttostr(buf[1])+' '+inttostr(buf[2])+' '
                                                 +inttostr(buf[3])+' '+inttostr(buf[4])+' '+inttostr(buf[5])+' '+inttostr(buf[6])+' ');
      if buf[0]<>0 then
        begin
        if buf[0]=1 then  //Прислали номер
          if buf[1]=0 then //Если номер = 0
            begin
            j:=1;
            While TankMas[j].n<>0 do inc(j);
            buf[0]:=2;
            buf[1]:=j;
            buf[2]:=1;
            buf[3]:=1;
            TankServer.Socket.Connections[i - 1].SendBuf(buf,bufd); 
            end;
        end;
      end;
    end;
  if updoTank=true then
    begin
      nomer;
      updoTank:=false;
    end;
  end;
end;
Нумерация по фактическому числу каналов:

Код:
for i := 1 to TankServer.Socket.ActiveConnections do
Физические номера каналов начиняются с 0. Отправка в конкретный канал по физическому номеру от фактической переменной счетчика:

Код:
TankServer.Socket.Connections[i - 1].SendBuf(buf,bufd);
Если бы счетчик считал от нуля:

Код:
for i := 0 to TankServer.Socket.ActiveConnections - 1 do
...было бы сложно ориентироваться в массиве объектов:

Код:
TankMas[i - 1].n
...но проще отсылать:

Код:
TankServer.Socket.Connections[i].SendBuf(buf,bufd);
Нужно просто помнить об этом всегда.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 11.08.2010, 20:47   #554
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Цитата:
Сообщение от Beermonza Посмотреть сообщение
Shouldercannon, длина пакета содержится в ServerSocket.Socket.ReceiveLength, присваивайте это некоторой переменной, затем переменную проверяйте на лимит.

Последовательность строго прописана. Что будет если в пакете первые два символа - числа, а сам он весит 1М ? ...сначала проверяйте на лимит пакета, вторым шагом - код команд, первые два символа. Затем соответствие длины пакета строгой команды. Не знаю как еще объяснить, может так:

1) Размер пакета меньше 2000 ?
Да: пропустить в шаг 2)
Нет: выполнить счет нарушения

2) Первые два символа числа ?
Да: пропустить в шаг 3)
Нет: выполнить счет нарушения

3) Есть ли команды с кодом, как были получены ?
Да: пропустить в шаг 4)
Нет: выполнить счет нарушения

4) Длина пакета команды соответствует длине по такому коду ?
Да: пропустить в обработку пакет
Нет: выполнить счет нарушения

Как только пользователь в короткий срок набрал штрафов до некоторого уровня, производите с ним действия.
Код:
...
function IsNumber(s: string): Boolean;
var
  i, v: integer;
begin
  Val(s, v, i);
  IsNumber := (i = 0);
end;
...
procedure TFormMain.ServerTimerTimer(Sender: TObject);
var
d: Integer;
Numbers: string;
begin
...
          // Условие, что пакет не пуст
          if text <> '' then
            begin
              //!//
              // Если размер пакета меньше или равно 2022
              if ServerSocket.Socket.ReceiveLength <= 2022 then // Команда 2 символа + длина сообщения 2000 символов + длина ника 20 символов
                else
                  d := d + 1; // Первое нарушение

              // Если первые два символа числа
              Numbers := Copy(text, 0, 2);

              if IsNumber(Numbers) then
                else
                  d := d + 1; // Второе нарушение

              // Есть ли команды с кодом, как были получены
              // ???

              // Если длина пакета команды соответствует длине по такому коду
              // ???
              //!//
Не понял шаги 3 и 4, код команды это 00, 01. Тормознуло
Цитата:
как были получены
.
Цитата:
Длина пакета команды соответствует длине по такому коду
длина команды это опять такиже 00, 01, 20 и тд их их длина равгая двум?

Последний раз редактировалось Shouldercannon; 12.08.2010 в 01:08.
Shouldercannon вне форума Ответить с цитированием
Старый 12.08.2010, 17:41   #555
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Shouldercannon, 3 шаг - это кейс:

Код:
  Case code of
  1: Begin
        // проверка на длину пакета

        GoTo L1;
      end;

  12: Begin
        // проверка на длину пакета

        GoTo L1;
      end;

  30: Begin
        // проверка на длину пакета

        GoTo L1;
      end;

  end;

  d := d + 1; // Третье нарушение

L1:
Поверка на длину пакета - это 4 шаг для каждого типа команды. Условие, что, например, в типе на изменение статуса должно быть столько то байт, ...если клиент пришлет пакет больше или меньше этой строгой длины, это будет посчитано как нарушение протокола.

code - это переменная, числовая, она должна содержать перевод двух символов Numbers в одно число: '00' - 0, '01' - 1, '30' - 30, и т.д.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 12.08.2010, 20:28   #556
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Из выше вами написанного я понял, что шаг 4 выполняется в шаге 3.
В case code of делать сверку только тип подтип команды (00, 10, 20 и тд.)?
Цитата:
code - это переменная, числовая, она должна содержать перевод двух символов Numbers в одно число: '00' - 0, '01' - 1, '30' - 30, и т.д.
Тогда не понятно. В первых двух случаях одно число, а в третье два. Под переводом вы имели ввиду StrToInt?
Прощу прощения за мой туготумизм если так можно вызариться, но что подразумевается под пакетом (код команды и подкоманды; ник юзера; текстовое сообщение)?

Последний раз редактировалось Shouldercannon; 12.08.2010 в 20:40.
Shouldercannon вне форума Ответить с цитированием
Старый 12.08.2010, 20:45   #557
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

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

Если первый символ равен "0", то на втором Try StrToInt({символ}); Except {действие} end;. В противном случае Try StrToInt({символы}); Except {действие} end;
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 13.08.2010, 15:42   #558
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Код:
  // Numbers - это первые два числа (тип и подтип). Например 00
  case code of // code в данном случае будет содержать 0 - только подтип
  0: begin
    // Проверка на длину пакета (длина для данного типа подкоманды)
    try
      StrToInt(text) <= 20 then // Длина ника. перед проверкой из text убрать первые два числа (тип и подтип)
    except
      // Подсчет нарушений
    end;

    GoTo L1;
  end;
Shouldercannon вне форума Ответить с цитированием
Старый 14.08.2010, 21:16   #559
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Shouldercannon, я вот сам написал абстрактные вещи и не проверил, ...StrToInt уже все делает, ну и отлично. Code должен содержать StrToInt(Numbers), все пакеты клиентов должны проходить через case code of.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 15.08.2010, 15:55   #560
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Код:
...
          // Условие, что пакет не пуст
          if text <> '' then
            begin
              //!//
              // Проверку на подленность
              // Проверка размера пакета
              if not ServerSocket.Socket.ReceiveLength <= 2022 then // Код команды + подкоманда 2 символа; сообщение 2000 символов; ник 20 символов
                d := d + 1; // Первое нарушение

              // Проверка первых двух символов на числа
              Numbers := Copy(text, 0, 2);

              if not IsNumber(Numbers) then
                d := d + 1; // Второе нарушение

              // Проверка команды
              code := StrToInt(Numbers);

              case code of
              00: begin
                // Проверка на длину пакета (отправленный с клиента ник)
                if StrToInt(text) <= 22 then // Код команды + подкоманда 2 символа; ник 20 символов
                  GoTo L1;
              end;

              10: begin
                // Проверка на длину пакета (отправленное с клиента сообщение)
                if StrToInt(text) <= 2002 then // Код команды + подкоманда 2 символа; сообщение 2000 символов
                  GoTo L1;
              end;

              11: begin
                // Проверка на длину пакета (отправленное с клиента приватное сообщение)
                if StrToInt(text) <= 2022 then // Код команды + подкоманда 2 символа; сообщение 2000 символов; ник 20 символов
                  GoTo L1;
              end;

              end;

              d := d + 1; // Третье нарушение

              L1:
              //!//
              // Получим код комманды, длину строки
              com := StrToInt(Copy(text, 1, 1));
              com2 := StrToInt(Copy(text, 2, 1));
              len := length(text) - 2;
              // Определение комманд
              case com of
              // Тип идентификации пользователей
              0: begin
...
И так дальше рулить в том же духе. Если всё верно, то после перехода к L1 (GoTo L1;) начнёт выполнение идущий далее код.
Shouldercannon вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
обновление в блоге - Создание клиент-сервера Pblog Обсуждение статей 0 03.10.2007 17:12
обновление в блоге - Диплом. Создание и продвижение сайта - готовь сани летом, а дипл Pblog Обсуждение статей 0 31.08.2007 20:00
обновление в блоге - USB Холодильник Pblog Обсуждение статей 0 25.06.2007 14:13
обновление в блоге - О ярлыках Pblog Обсуждение статей 0 27.05.2007 03:17