
30.12.2009, 16:45
|
|
Moderator - Level 7
Регистрация: 02.05.2009
Сообщений: 894
С нами:
8960826
Репутация:
2261
|
|
чорд
а когда я разбирался с вин-соком, фиг я эту статью нашел(
отличная статья для начинающих.
еще один +1 в пользу необходимости разделения раздела "наши статьи" на тематические подразделы
ps
открыл для себя набор интересного чтива под названием "все темы c slesh" 
Последний раз редактировалось ErrorNeo; 30.12.2009 в 16:55..
|
|
|

30.12.2009, 18:42
|
|
Участник форума
Регистрация: 10.08.2009
Сообщений: 238
С нами:
8817310
Репутация:
108
|
|
Да, для новичков самое то. Сам с удовольствием прочитал, буду ждать 3-4 части.
|
|
|

31.12.2009, 10:20
|
|
Участник форума
Регистрация: 22.11.2008
Сообщений: 142
С нами:
9193651
Репутация:
32
|
|
Вот, я тут решил немного почудить в стиле PHP.
Короче вот код.
Пусть дети играются.
Код:
unit FSockets; {(c)Flenov forum.antichat}
interface
uses
SysUtils, WinSock2;
type
TFSocket = TSocket;
function FSocketsInicialize(Version: Word=$0202): Integer;
function FSockOpen(Host: String; Port: Word): TFSocket;
function FPuts(Sock: TFSocket; Str: String): Integer;
function FGets(Sock: TFSocket; var Size: Integer): String;
function FRedySend(Sock: TFSocket; Timeout: LongWord=10): Boolean;
function FRedyRead(Sock: TFSocket; Timeout: LongWord=10): Boolean;
function FClose(Sock: TFSocket): Integer;
function FSocketsDeinicialize: Integer;
implementation
function FSocketsInicialize(Version: Word=$0202): Integer;
var
wData: TWSAData;
begin
Result:=WSAStartup(Version, wData);
end;
function FSockOpen(Host: String; Port: Word): TFSocket;
var
Sock: TFSocket;
SockAddr: TSockAddrIn;
HostEnt: PHostEnt;
InAddr: TInAddr;
FDSet: TFDSet;
begin
Result:=0;
HostEnt:=GetHostByName(PChar(Host));
if (HostEnt=nil) then Exit;
FillChar(InAddr, SizeOf(InAddr), 0);
With InAddr, HostEnt^ do
begin
S_un_b.s_b1:=Byte(h_addr^[0]);
S_un_b.s_b2:=Byte(h_addr^[1]);
S_un_b.s_b3:=Byte(h_addr^[2]);
S_un_b.s_b4:=Byte(h_addr^[3]);
end;
SockAddr.sin_family:=AF_INET;
SockAddr.sin_addr:=InAddr;
SockAddr.sin_port:=HToNS(Port);
FillChar(SockAddr.sin_zero, SizeOf(SockAddr.sin_zero), 0);
Sock:=Socket(AF_INET, SOCK_STREAM, 0);
if (Sock<>INVALID_SOCKET) then
if (Connect(Sock, @SockAddr, Sizeof(SockAddr))<>SOCKET_ERROR) then Result:=Sock
else CloseSocket(Sock);
end;
function FPuts(Sock: TFSocket; Str: String): Integer;
begin
Result:=Send(Sock, PChar(Str)^, Length(Str), 0);
end;
function FGets(Sock: TFSocket; var Size: Integer): String;
var
Buff: PChar;
begin
Buff:=GetMemory(Size);
try
Size:=Recv(Sock, Buff^, Size, 0);
Result:=Copy(Buff, 1, Size);
finally
FreeMemory(Buff);
end;
end;
function FRedySend(Sock: TFSocket; Timeout: LongWord=10): Boolean;
var
WFDS: TFDSet;
tv: TTimeVal;
begin
Result:=False;
tv.tv_sec:=Timeout;
tv.tv_usec:=0;
FD_ZERO(WFDS);
FD_SET(Sock, WFDS);
if FD_ISSET(Sock, WFDS) then
if (Select(0, nil, @WFDS, nil, @tv)=1) then Result:=True;
end;
function FRedyRead(Sock: TFSocket; Timeout: LongWord=10): Boolean;
var
RFDS: TFDSet;
tv: TTimeVal;
begin
Result:=False;
tv.tv_sec:=Timeout;
tv.tv_usec:=0;
FD_ZERO(RFDS);
FD_SET(Sock, RFDS);
if FD_ISSET(Sock, RFDS) then
if (Select(0, @RFDS, nil, nil, @tv)=1) then Result:=True;
end;
function FClose(Sock: TFSocket): Integer;
begin
Result:=CloseSocket(Sock);
end;
function FSocketsDeinicialize: Integer;
begin
Result:=WSACleanup;
end;
end.
|
|
|

31.12.2009, 10:27
|
|
Участник форума
Регистрация: 22.11.2008
Сообщений: 142
С нами:
9193651
Репутация:
32
|
|
|
|
|

31.12.2009, 19:22
|
|
Banned
Регистрация: 26.12.2009
Сообщений: 152
С нами:
8618486
Репутация:
0
|
|
А вот ещё вопрос на засыпку:
Какие коды ошибок (кроме -1) могут вернуть Send и Recv?
|
|
|

01.01.2010, 01:28
|
|
Участник форума
Регистрация: 22.11.2008
Сообщений: 142
С нами:
9193651
Репутация:
32
|
|
Да наверно получается, что -1 единственный код ошибки
|
|
|

22.02.2010, 02:01
|
|
Постоянный
Регистрация: 04.12.2007
Сообщений: 424
С нами:
9702986
Репутация:
479
|
|
На windows 7 существуют варианты использовать сырые сокеты? (без всяких winpcap)
|
|
|

06.03.2010, 18:23
|
|
Новичок
Регистрация: 16.02.2010
Сообщений: 14
С нами:
8543927
Репутация:
1
|
|
Уважаемый slesh, я вижу вы неплохой специалист в области сетевого программирования.
Если знаете, подскажите пожалуйста такой вопрос:
В PHP сокеты можно сравнить с файлами и там есть такая замечательная функция feof, которая возвращает true если все данные считаны и соответственно false если нет.
Есть ли аналог подобной функции в Delphi.
Теперь зачем мне это:
Дело в том, что я создаю небольшой TCP клиент, и я хочу не разрывать соединение.
Вот мне как раз и нужно знать получил ли я все данные или нет.
Если тупо использовать recv и ждать, когда она вернёт 0 - это не вариант.
Она просто тупо зависнет если я её вызову после приёма всех данных.
Вот мне и нужнол решение.
Подскажите, если знаете.
Заранее спасибо.
|
|
|

06.03.2010, 19:59
|
|
Постоянный
Регистрация: 13.12.2008
Сообщений: 354
С нами:
9162683
Репутация:
175
|
|
Сообщение от #Specan
Уважаемый slesh, я вижу вы неплохой специалист в области сетевого программирования.
Если знаете, подскажите пожалуйста такой вопрос:
В PHP сокеты можно сравнить с файлами и там есть такая замечательная функция feof, которая возвращает true если все данные считаны и соответственно false если нет.
Есть ли аналог подобной функции в Delphi.
Теперь зачем мне это:
Дело в том, что я создаю небольшой TCP клиент, и я хочу не разрывать соединение.
Вот мне как раз и нужно знать получил ли я все данные или нет.
Если тупо использовать recv и ждать, когда она вернёт 0 - это не вариант.
Она просто тупо зависнет если я её вызову после приёма всех данных.
Вот мне и нужнол решение.
Подскажите, если знаете.
Заранее спасибо.
#Specan, немного неправильно.
Если подключение, открытое при помощи fsockopen() не было закрыто сервером, feof() будет ждать достижения таймаута прежде чем вернуть TRUE. Время таймаута по умолчанию равно 60 секундам. Вы можете использовать stream_set_timeout() для того, чтобы изменить это значение.
То есть сервак должен закрыть соединение, что бы данная функция возвратила True.
Сообщение от #Specan
Дело в том, что я создаю небольшой TCP клиент, и я хочу не разрывать соединение.
Лично я думаю, что вы должны использовать какие то особенности своего внутреннего протокола. Например, при получении определенных данных перестать читать из сокета.
Хотя я точно не уверен насчет всего этого, поэтому если что, пусть slesh ответит. Он укажет более правильный вариант.
|
|
|

06.03.2010, 20:19
|
|
Новичок
Регистрация: 16.02.2010
Сообщений: 14
С нами:
8543927
Репутация:
1
|
|
Спасибо за ответ!
Получается php feof можно сравнить с delphi sellect?
|
|
|
|
Предыдущая тема
Следующая тема
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|