![]() |
|
|
#1
|
||||
|
||||
|
Привет всем! Подскажите пожалуйста, как в WinSock в блокирующих сокетах установить свой таймаут подключения и принятия пакетов?! Интересуют именно блокирующие сокеты. Спасибо заранее.
|
|
#2
|
||||
|
||||
|
при подключении переводи сокет в неблокирующий режим через 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; |
|
#3
|
||||
|
||||
|
NumLock, connect Возвращает -1. после коннекта ошибка по таймауту, хотя в браузере например открывается норм. запарился я с этими винсоками. Подскажи плиз любой хороший компонент, который как инди бы в 1 строку без лишних проблем подключился к серверу и еще в 1 следующую строку прочитал сразу же входящий пакет(массив байтов).
|
|
#4
|
||||
|
||||
|
это работает?
http://data.cod.ru/121376 |