
25.08.2011, 09:22
|
 |
Let Me Show You
|
|
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
|
|
при подключении переводи сокет в неблокирующий режим через ioctlsocket, потом select с таймаутом ожидай завершения операции connect, потом обратно в блокирующий режим.
при чтении опять же через select определяй readability статус у сокета.
Код:
procedure connect;
var
WSAData: TWSAData;
FSocket: TSocket;
FAddr: sockaddr_in;
arg: Integer;
ErrorCode: Integer;
FDSetW: TFDSet;
FDSetE: TFDSet;
TimeVal: TTimeVal;
const
FTimeOutConnect: Cardinal = 5000;
begin
WSAStartup($0101, WSAData);
FSocket:=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
FAddr.sin_family:=AF_INET;
FAddr.sin_port:=htons(80);
FAddr.sin_addr.S_addr:=inet_addr(PChar('74.125.232.51'));
arg:=1;
ioctlsocket(FSocket, FIONBIO, arg);
if WinSock.connect(FSocket, FAddr, SizeOf(FAddr))<>0 then
begin
ErrorCode:=WSAGetLastError;
if ErrorCode<>WSAEWOULDBLOCK then
raise Exception.Create('connect(): '+SysErrorMessage(ErrorCode));
FD_ZERO(FDSetW);
FD_ZERO(FDSetE);
FD_SET(FSocket, FDSetW);
FD_SET(FSocket, FDSetE);
TimeVal.tv_sec:=FTimeOutConnect div 1000;
TimeVal.tv_usec:=(FTimeOutConnect mod 1000)*1000;
select(0, nil, @FDSetW, @FDSetE, @TimeVal);
if not FD_ISSET(FSocket, FDSetW) then
raise Exception.Create('connect(): timeout');
end;
arg:=0;
ioctlsocket(FSocket, FIONBIO, arg);
end;
function recv(FSocket: TSocket; var Buf; Count: Integer): Integer;
var
ErrorCode: Integer;
FDSet: TFDSet;
TimeVal: TTimeVal;
const
FTimeOutRead: Cardinal = 5000;
begin
FD_ZERO(FDSet);
FD_SET(FSocket, FDSet);
TimeVal.tv_sec:=FTimeOutRead div 1000;
TimeVal.tv_usec:=(FTimeOutRead mod 1000)*1000;
if select(0, @FDSet, nil, nil, @TimeVal)=SOCKET_ERROR then
raise Exception.Create('recv: invalid socket');
if not FD_ISSET(FSocket, FDSet) then
raise Exception.Create('recv(): timeout');
Result:=WinSock.recv(FSocket, Buf, Count, 0);
if Result=0 then
begin
closesocket(FSocket);
raise Exception.Create('recv: closed');
end;
if (Result=SOCKET_ERROR) then
begin
ErrorCode:=WSAGetLastError;
closesocket(FSocket);
raise Exception.Create('recv: '+SysErrorMessage(ErrorCode));
end;
end;
__________________
Пишу программы за еду.
__________________
|