Тема: WinSock API
Показать сообщение отдельно
  #14  
Старый 28.12.2010, 14:39
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Код:
procedure TServerClientThread.ClientExecute;
var
  FDSet: TFDSet;
  TimeVal: TTimeVal;
begin
  while not Terminated and ClientSocket.Connected do
  begin
    FD_ZERO(FDSet);
    FD_SET(ClientSocket.SocketHandle, FDSet);
    TimeVal.tv_sec := 0;
    TimeVal.tv_usec := 500;
    if (select(0, @FDSet, nil, nil, @TimeVal) > 0) and not Terminated then
      if ClientSocket.ReceiveBuf(FDSet, -1) = 0 then Break
      else Synchronize(DoRead);
    if (select(0, nil, @FDSet, nil, @TimeVal) > 0) and not Terminated then
      Synchronize(DoWrite);
  end;
end;
В компоненте ServerSocket вечно проверяется, есть ли буфер для чтения или записи, если есть для чтения - вызывают функцию его чтения.
Код:
function TCustomWinSocket.ReceiveBuf(var Buf; Count: Integer): Integer;
var
  ErrorCode, iCount: Integer;
begin
  Lock;
  try
    Result := 0;
    if (Count = -1) and FConnected then
      ioctlsocket(FSocket, FIONREAD, Longint(Result))
    else begin
      if not FConnected then Exit;
      if ioctlsocket(FSocket, FIONREAD, iCount) = 0 then
      begin
        if (iCount > 0) and (iCount < Count) then
          Count := iCount;
      end;

      Result := recv(FSocket, Buf, Count, 0);
      if Result = SOCKET_ERROR then
      begin
        ErrorCode := WSAGetLastError;
        if ErrorCode <> WSAEWOULDBLOCK then
        begin
          Error(Self, eeReceive, ErrorCode);
          Disconnect(FSocket);
          if ErrorCode <> 0 then
            raise ESocketError.CreateResFmt(@sWindowsSocketError,
              [SysErrorMessage(ErrorCode), ErrorCode, 'recv']);
        end;
      end;
    end;
  finally
    Unlock;
  end;
end;
Если эту функцию я правильно понял, то получается, что если прочитать не удалось то клиента отключают со стороны сервера.
Тогда не удивительно, что функция для ASocket начинает возвращать ошибку - ведь ASocket это число, ссылка. Сам сокет уже закрыт сервером т.к. была ошибка чтения.

Почитал код ServerSocket - решил встроить такую же проверку в свой код.

Встроил. Вроде работает нормально. Спасибо NumLock, что направили на этот компонент. По умолчанию его в Delphi XE нету...
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием