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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 31.07.2014, 02:00   #1
STRELOK-2007
Форумчанин
 
Регистрация: 06.08.2009
Сообщений: 144
Восклицание Работа с сокетом

Приветствую!
Помогите пожалуйста с проблемой!

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

Затем сервер переключает режим сокета:
Код:
 UV:=0;
 ioctlsocket(FSocked, FIONBIO, UV);
 FillChar(swapBuffer, SizeOf(swapBuffer), 0);
и начинает в цикле слушать:
Если сокет выбрался, значит в нем что-то есть и можно получить.

У меня всегда посылаются маленький рабор данных, максимум 44 байта. Обычно 14-18 байт, поэтому, считаю что, если что-то пришло - значит это наш пакет, посланный клиентом.
Код:
 FD_ZERO(FD);
 _FD_SET(FSocked, FD);

 TV.tv_sec:=2;
 SocketSet:= select(0, @FD, @FD, nil, @TV);

 if FD_ISSET(FSocked, FD) then
  begin
   ...
  end;
И тут начинается свистопляска.
То клиент виснет на посылке сообщения, то виснет на приеме сообщения-ответа.
То вроде как отправилось, но на клиент ничего не пришло.
То вроде как пришло, пакет читается, но ID всегда 0.

С сокетами последний раз работал полтора года назад, тогда все шло все гладко.

Что я делаю не так?
Проект должен был еще вчера сдавать, но просидел весь вечер и ночь с этими "дырками".

Может быть как-то по-другому сделать надо?
Все это нужно для межпроцессного взаимодействия, сокеты выбрал лучшим вариантом. В процессе идет работа с устройством, бывает что, иногда, процесс виснет наглухо и его надо перезапускать.
Именно поэтому, решил каждое устройство выделить в отдельном процессе - повиснет и бог с ним, главное что сервер-хост жив-здоров и может штатно перезапустить.

А я залип с этими сокетами.

P.S.
3 параметр в select добавил недавно, до этого было nil - тоже особо не помогало.

В клиенте тоже пытался делать так:
Код:
 UV:=0;
 ioctlsocket(hSocket, FIONBIO, UV);
 FillChar(swapBuffer, SizeOf(swapBuffer), 0);
 TV.tv_sec:=2;

 FD_ZERO(FD);
 _FD_SET(hSocket, FD);

 TV.tv_sec:=2;
 SocketSet:= select(0, @FD, @FD, nil, @TV);
3 параметр так-же здесь появился недавно.

Заранее, спасибо!
STRELOK-2007 вне форума Ответить с цитированием
Старый 31.07.2014, 07:45   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
поэтому, считаю что, если что-то пришло - значит это наш пакет, посланный клиентом.
А если это какой-нибудь вирус пингует этот порт, засылая свои пакеты?
И ты это принимаешь в цикле?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 31.07.2014, 08:16   #3
STRELOK-2007
Форумчанин
 
Регистрация: 06.08.2009
Сообщений: 144
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
А если это какой-нибудь вирус пингует этот порт, засылая свои пакеты?
И ты это принимаешь в цикле?
Хм, и как тогда поступить в таком случае?
Позднее, планирую добавить симметричное шифрование пакетов с ассиметричным обменом ключа шифрования.
STRELOK-2007 вне форума Ответить с цитированием
Старый 31.07.2014, 13:23   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

А я даже не знаю... Сам такую защиту на свои проги не вешал.
Я принимаю пакеты в цикле, но у меня кол-во байт каждого пакета передается заранее, поэтому я знаю когда и сколько считывать из буфера.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 31.07.2014, 21:25   #5
STRELOK-2007
Форумчанин
 
Регистрация: 06.08.2009
Сообщений: 144
Восклицание

Цитата:
Сообщение от Stilet Посмотреть сообщение
А я даже не знаю... Сам такую защиту на свои проги не вешал.
Я принимаю пакеты в цикле, но у меня кол-во байт каждого пакета передается заранее, поэтому я знаю когда и сколько считывать из буфера.
То-же самое.
Когда то давно я писал бота для одной из онлайн игрушек, там использовался Netty протокол для создания пакетов.
Написал класс, втянулся, понравилось.

Код:
 FD_ZERO(FD);
 _FD_SET(FSocked, FD);

 TV.tv_sec:=2;
 SocketSet:= select(0, @FD, @FD, nil, @TV);

 if FD_ISSET(FSocked, FD) then
  begin
   c:= recv(Device.SockedCurrent, swapBuffer, 65536, MSG_PEEK);

   if c = SOCKET_ERROR then
    Exit;

   if c = 0 then
    Exit;

   //MonitorLog(lrtMessage, 'Incomming TCP packet: size '+IntToStr(c));

   Res:= Proto.NettyRecv(Netty);

   //MonitorLog(lrtMessage, Format('Incomming Netty packet: %s, ID = %d, Length = %d', [BoolToStr(Res, true), Netty.ID, Netty.Length]));
Код:
function TssProtocol.NettyRecv(var Netty: TNetty): Boolean;
var
 Header: TssPacketHeader;
 Buf: AnsiString;
begin
 Result:= False;

 if not SocketRecv(Header, ssAuchPacketHeader) then
  begin
   Exit;
  end;

 if header.Length > 0 then
  begin
   SetLength(Buf, header.Length);

   if not SocketRecv(Buf[1], Header.Length) then
    begin
     Exit;
    end;
  end
 else
  buf:='';

 Netty.ID:= Header.ID;
 Netty.Reserved1:= Header.Reserved1;
 Netty.Reserved2:= Header.Reserved2;

 Netty.asString:= Buf;

 Result:= True;
end;
STRELOK-2007 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проверить соединение с сокетом Aleksandr Работа с сетью в Delphi 1 24.11.2013 10:41
Проблема с Сокетом(открытие порта) karimchik666 C/C++ Сетевое программирование 1 26.05.2011 15:33
Отослать необъявленый массив сокетом Johnson Работа с сетью в Delphi 1 27.12.2010 08:01
как сделать с сокетом cargo29 Общие вопросы Delphi 4 20.12.2010 22:02