Модераторы: Snowy, Poseidon, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Правильное отключение сокета. close_wait 
:(
    Опции темы
CynicRus
Дата 31.3.2015, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 31.5.2012

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



Приветствую уважаемых форумчан. Имеется самописный сервер, всё отлично принимает, обслуживает клиентов. При этом клиенты писаны на ActiveScript 3 и используют флешовые сокеты. Однако периодически, когда клиент отключается, остаётся висеть зомби коннект в состоянии CLOSE_WAIT. На данный момент обсулживание клиента выглядит так:
Код

procedure TTCPServer.ClientThread;
var
  ID: NativeUInt;
  Error, BytesTransferred: Cardinal;
  pOvr: POverlapped;
  pOper: PTCPOperation;
begin
  while not FThreadPoolAborted do
  begin
    ID := 0;
    BytesTransferred := 0;
    if not GetQueuedCompletionStatus(FCompletionPort, BytesTransferred, ID,
      POverlapped(pOvr), 250) then
    begin
      Error := GetLastError;
      if (Error = WAIT_TIMEOUT) or (ID = 0) then
        Continue;
    end;

    // Клиент отключился
    if (BytesTransferred = 0) and (pOvr = nil) then
    begin
      if pOvr <> nil then
        OperationDestroy(pOvr, True);
      Disconnect(ID);
      Continue;
    end;
    if pOvr <> nil then
    begin
      pOper := Pointer(pOvr^.Offset);
      case pOper^.OperationType of
        ServerOperationRecv: // Приём
          begin
            InterlockedDecrement(FOperationsPending);
            if BytesTransferred > 0 then
              DataReceived(ID, pOper^.Buffer.Buf, BytesTransferred);
            try
              if ID and $FFFFF000 <> 0 then
                Exit;
                 ReceiveDataPending(pOvr);
            except
              OperationDestroy(pOvr, True);
              Disconnect(ID);
            end;
          end;

        ServerOperationSend:
          begin
            InterlockedDecrement(FOperationsPending);
            pOper^.Success := BytesTransferred = pOper^.Buffer.len;
            // Отправитель ожидает результат?
            if pOper^.OperationDone <> 0 then
            begin
              SetEvent(pOper^.OperationDone);
              WaitForSingleObject(pOper^.ReadyToDestroy, INFINITE);
            end;
            if pOper^.Success then
              DataSended(ID, pOper^.Buffer.Buf, BytesTransferred)
            else
              Disconnect(ID);
            OperationDestroy(pOvr, True);
          end;
      end;
    end;
    Sleep(10);
  end;

  InterlockedDecrement(FActiveThreadsCount);
end;


Структура TCPOperation:
Код

PTCPOperation = ^TTCPOperation;

  TTCPOperation = record
    OperationType: Integer;
    Socket: TSocket;
    Buffer: WSABUF;
    Success: Boolean;
    OperationDone: THandle;
    ReadyToDestroy: THandle;
  end;


Disconnect:
Код

procedure TTCPServer.Disconnect(ID: Integer; FlushData: Boolean);
var
  Conn: TTCPConnection;
begin
  Lock('Disconnect');
  try
    try
    Conn := FConnections.ItemByID(ID);
    if Conn = nil then
      Exit;
    FConnections.Remove(Conn);
    except
    on E: Exception do
      raise Exception.Create('TTCPServer.Disconnet');
    end;
  finally
  if Conn <> nil then
   begin
      uWinSock2.shutdown(Conn.Socket, SD_BOTH);
      ClientDisconnected(Conn);
      Conn.Free;
   end;
   Unlock('Disconnect');
  end;

end;


Деструктор коннекта:
Код

destructor TTCPConnection.Destroy;
begin
  Self.CloseSocket;
  if FBuffer <> nil then
    FBuffer.Free;
  inherited;
end;

procedure TTCPConnection.CloseSocket;
begin
  if FSocket <> INVALID_SOCKET then
  begin
    uWinSock2.closesocket(FSocket);
    FSocket := INVALID_SOCKET;
  end;
end


Собственно вопрос заключается в том, что я делаю неправильно при отключении клиента, что остаётся висеть зомби процесс, и как сделать правильно, чтобы оных не оставалось?

Это сообщение отредактировал(а) CynicRus - 31.3.2015, 09:15
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

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


 




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


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

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