Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.03;
Скачать: CL | DM;

Вниз

Странности у TTcpClient и TTcpServer   Найти похожие ветки 

 
SpellCaster   (2006-07-04 19:52) [0]

Товарищи! Для решения глобальной задачи написал простенький тестер. Есть TTcpClient и TTcpServer. Сервер по таймеру пишет в поток данные (допустим, текущие секунды), а клиент постоянно в цикле читает из этого буфера. Так вот, по идее после первого прочтения буфер должен быть пуст - но нет, там остается второй байт, извлекаемый из буфера только при втором прочтении. При этом количество прочитанных байт (TcpClient1.ReceiveBuf(Buf,size) ) всегда почему-то равно 255. Как можно проверить целостность полученного сообщения, если потенциально его размер неизвестен?
И еще. Пытаюсь "навесить" серверу события, типа OnAccept, но из всех вызывается почему-то только CreateHandle. Причем если событиям присвоены обработчики, при закрытии формы возникает Exception, без обработчиков все нормально. Это что-то у меня глючит, или как?
Заранее спасибо.

procedure TForm1.Button1Click(Sender: TObject);
begin
Timer1Timer(nil);
Server1.Active:=True;
Client1.Active:=True;
Client1.Connect;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
s:=inttostr(SecondOf(Time));
StrCopy(PChar(Buf),PChar(s));
size:=Length(s);
Label1.Caption:=s;
Server1.SendBuf(Buf,size);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Buf:=PByte(AllocMem(MaxMsgLen));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
msg: array of Byte;
i: byte;
begin
i:=client1.ReceiveBuf(Buf,size);

SetLength(msg,3);
msg[0]:=Buf^;
inc(buf);
msg[1]:=Buf^;
msg[2]:=0;
log(PChar(@msg[0]));
log(inttostr(i));
end;


 
Slym ©   (2006-07-05 09:45) [1]

TTcpClient - юзать еще можно, но вот TTcpServer использовать не стоит пользуй TServerSocket


 
SpellCaster   (2006-07-05 10:10) [2]

Почему? Глючный? Дело в том, что сервер будет не мой, удаленный, а я сейчас набросал нечто вроде эмулятора. Все, что от него требуется - раз в секунду бросать данные.
Или лучше юзать как Серверсокет, так и Клиентсокет?


 
medved_68 ©   (2006-07-05 10:39) [3]


> Так вот, по идее после первого прочтения буфер должен быть
> пуст - но нет, там остается второй байт, извлекаемый из
> буфера только при втором прочтении.


> var
> msg: array of Byte;
> i: byte;
> begin
> i:=client1.ReceiveBuf(Buf,size);

Странно в byte пытаешься записать size:=Length(s); Тогда уж читай в цикле и набивай msg. А условие выхода = size;

>  Как можно проверить целостность полученного сообщения,
> если потенциально его размер неизвестен?

size:=int64;
загоняй его в буфер первым передавай и при приеме проверяй по нему все ли считал :)))


> Пытаюсь "навесить" серверу события, типа OnAccept,

А где ты увидел у IdTCPServer такое событие????


 
SpellCaster   (2006-07-05 13:37) [4]


> Странно в byte пытаешься записать size:=Length(s); Тогда
> уж читай в цикле и набивай msg. А условие выхода = size;
>

Так s - это строка, ее длина не больше 255...
А ReceiveBuf(Buf,size); почему-то всегда возвращает -1 (который из-за беззнаковости byte превращается в 255).
К тому же если повесить на клиента событие OnError, то перед каждым действием возникает ошибка "10035 Операция на незаблокированном сокете не может быть завершена немедленно". Клиенту я поставил blockmode=bmNonBlocking, т.к. в противном случае прога виснет.


> size:=int64;
> загоняй его в буфер первым передавай и при приеме проверяй
> по нему все ли считал :)))

Вообще да, в реальном серваке будут посылаться сообщения с сигнатурой окончания, можно будет по ним проверять. Просто меня удивило, что вроде бы байт уже прочитан, а в буфере он остается.


> А где ты увидел у IdTCPServer такое событие????

Это не Инди, это ТTCPServer. Инди у меня вообще глючит безбожно, посылает вроде нормально, а получает - лабуду всякую :(

P.S. Фух, наконец-то нашел, куда бормановцы засунули TServerSocket
и TClientSocket. Надо поробовать с этими компонентами.


 
medved_68 ©   (2006-07-05 14:05) [5]

>
> SpellCaster

Server1.SendBuf(Buf,size);

посылаешь неправильно если Buf:string то SendBuf(Buf[1],size);
а если Buf:array чего то то SendBuf(Buf[0],size); где size размер либо строки либо отправляемого буфера.

> Это не Инди, это ТTCPServer. Инди у меня вообще глючит безбожно,
>  посылает вроде нормально, а получает - лабуду всякую :(

Неправда. При таком подходе как [0] ты и с TServerSocket, TClientSocket получишь лабуду на приеме. А насчет ТTCPServer я правда всего пару прог на нем рихтовал, нормально тоже работает, зря на него бочку катишь!!!!


 
SpellCaster   (2006-07-05 14:08) [6]

Поправка: оказывается, я юзал один и тот же буфер для принятия и получения ((. После того как сделал два буфера, выяснил, что данные вообще не приходят! Постоянно возникает эта долбаная  ошибка 10035!
*спокойно, спокойно, дыши глубже...*
Буду разбираться с ТхххСокет.


 
medved_68 ©   (2006-07-05 14:10) [7]

Исправь передачу буфера как [5] тогда будет все чики чики


 
SpellCaster   (2006-07-05 17:02) [8]

Забил на все эти странные компоненты, заюзал чисто ТхххСокет. Пока что вроде бы пашет. Повесил чтение данных на ClientSocket.OnRead.


 
medved_68 ©   (2006-07-05 17:13) [9]


> SpellCaster


> Забил на все эти странные компоненты

Тоже Выход!!!! Я бы тоже забил но.....:)))))


 
Untermensch   (2006-07-06 09:56) [10]

Странно написал уже несколько программ с инди10, всё замечательно работает, очень удобная потоковая структура сервера, единственное что, для передачи пользую обычные строки кодированые в чём нить типа base64, т.е. текст и типовой маркер конца сообщения #13#10. В качестве буфера везде испольуются обычные длинные текстовые строки дельфи (вернее адрес первого байта строки).
Сбор и разбор строк выполняет сама программа. На сервере - службе 30 клиентов, 50 потоков, общение с базой и периферией, и ни одной жалобы на indy система рабоает сутками без перезапуска. Утомляет правда отлов ексепшона на клиенте, если он сервера не видит (чего им, событий не хватило, что ли, ну нет сервера и нет, падать то зачем). А кодировка блока в base64 как раз и призвана исключить всё загадочное поведение канала (типа Трима младших кодов меньше 32). А ещё, одно замечание, у инди есть какое то ограничение на размер буфера в сокете, не помню точно, но при больших размерах она выдаёт ексепшон) потому большие пакеты желательно делить на маленькие и собирать там же где осуществляется кодировка. Оптимально передавать где то по 4-16кб.


 
SpellCaster   (2006-07-06 11:20) [11]

Untermensch
Были бы строки, я бы не стал так париться - со строками вроде всё нормально пашет. Трабла в том, что надо принимать двоичные данные - а я не уверен, будет ли Инди передавать строки с нулями в середине.

medved_68
А что мешает? ;)


 
Untermensch   (2006-07-06 11:31) [12]

Я имел ввиду, что если клиент и сервер пишутся в рамках одного проекта, то проще перешифровывать данные канала в BASE64 чтоб не ломать потом голову что и как потерялось, а если использовать собственную базу символов для кодирования, это ещё и быстро отобьёт желание у сниферменов ломать данный протокол.
А насчёт нолей - они нормально проходят если в середине, проблема когда 0 стоит перед маркером конца, т.к. инди например его зачем то сьедает.


 
medved_68 ©   (2006-07-06 12:46) [13]


> SpellCaster


> medved_68
> А что мешает? ;)

Прогресс, блин....:))))

> Трабла в том, что надо принимать двоичные данные - а я не
> уверен, будет ли Инди передавать строки с нулями в середине.
>

Будет и нормально. Я например если размеры передаваемого блока меняются перед передачей конкретного блока забиваю в буфер его размер обычно INT64 а при приеме первого блока считываю его в отдельную переменную затем принимаю весь блок, сливаю в поток и проверяю совпадают ли размеры. Если да то можно и подтвердить прием тут уж конкретно от алгоритма, можно и запрос на повтор выставить серверу, и нормально ничего не теряется и не съедается. Что ИНДИ что СерверСокет работают одинаково. Вообщем все траблы от непродуманности прием-передачи по каналу (по крайней мере у меня были), как только решил сей вопрос, стало фиолетово какой компонент использовать они примерно все одинаковы в смысле работы с каналом связи. Вопрос в удобстве использования.

P.S. Кстати передачей я пользуюсь только SendStream, удобство так сказать ,отправил поток и забыл....


 
SpellCaster   (2006-07-06 17:57) [14]

Ладно, пока что фурычит, начнет глючить - снова начну всех тормошить :). А с выбором способа приема подожду, пока не появится реальный сервак, буду уже на нем тестить.
Всем спасибо за внимание и помощь! =)


 
SpellCaster   (2006-07-07 17:31) [15]

Снова я )))
Проблема такая: создаю новый класс нити (Thread), уже в ней создаю Клиентсокет. Все вроде бы нормально, но в процедуре Execute почему-то не выполняется коннект (active:=true)! Т.е. эта строчка просто проходится, и прога выполняется дальше. Ладно, перешел на блокирующие сокеты... вроде во всем разобрался, только неясно: в этом случае обязательно юзать TWinSocketStream?
Итак, вопросов 2:
1. Почему не выполняется коннект сокета в методе Execute потока
2. Надо ли юзать TWinSocketStream, при условии что вероятны обрывы связи, а навечно зависший на строчке fClient.Socket.ReceiveBuf(fDestBuf^,size); код не подходит?
2а. Надежен ли ReceiveLength, т.е. вероятна ли ситуация, когда там ненулевое значение, а при чтении буфера связь разрывается?

...немного путано, но уже конец рабочего дня, а спать жуть как охота ))


 
Ketmar ©   (2006-07-08 13:27) [16]

2. навечно оно там не зависнет. в конце концов вылетит по тайм-ауту.


 
medved_68 ©   (2006-07-08 16:00) [17]


> 2. навечно оно там не зависнет. в конце концов вылетит по
> тайм-ауту.

Если в неблокирующем режиме то навряд ли, будет ждать пополнения буфера из сокета.

> SpellCaster


> Проблема такая: создаю новый класс нити (Thread), уже в
> ней создаю Клиентсокет


> вроде бы нормально, но в процедуре Execute почему-то не
> выполняется коннект (active:=true)! Т.е. эта строчка просто
> проходится, и прога выполняется дальше.

А событие ОНКОННЕКТ клиента привязал в нити???? Это если не в блоке.

> Ладно, перешел на блокирующие сокеты... вроде во всем разобрался,
>  только неясно: в этом случае обязательно юзать TWinSocketStream?
>

Нет необязательно. Можешь читать теми же методами их никто не отменял. Другое дело как узнать когда необходимо читать??? Ведь в блоке уведомлений в виде событий нет!!!! А у TWinSocketStream есть таймаут по которому можно продолжать выполнение треда даже если нет ожидаемых данных. :)))

> 2а. Надежен ли ReceiveLength, т.е. вероятна ли ситуация,
>  когда там ненулевое значение, а при чтении буфера связь
> разрывается?

ненулевое значение установится только при полном приеме из сокета</B. если произойдет сбой во время приема очередного блока то просто будет либо ИС, либо ОНКЛИЕНТЕРРОР, в зависимости от режима работы сокета.
>
> а при чтении буфера связь разрывается?

Ты читаешь буфер когда он уже загружен т.е. очередной сеанс связи прошел успешно. Наверное действительно необходимо:"Если хочешь поработать, ляг поспи и все пройдет". :))))


 
Ketmar ©   (2006-07-09 11:54) [18]

>medved_68 ©   (08.07.06 16:00) [17]
не думаю, что в неблокирующем нет тайм-аутов. но точно не знаю -- никогда не использовал этот режим. %-)


 
Slym ©   (2006-07-10 10:10) [19]

SpellCaster   (07.07.06 17:31) [15]
1. Почему не выполняется коннект сокета в методе Execute потока

Если ошибка не вывалилась значит выполнилось.
SpellCaster   (07.07.06 17:31) [15]
2. Надо ли юзать TWinSocketStream, при условии что вероятны обрывы связи,

Условия не причем, ни кто тебе не мешает выдрать код ожидания из TWinSocketStream
SpellCaster   (07.07.06 17:31) [15]
Надежен ли ReceiveLength, т.е. вероятна ли ситуация

Надежен и вероятна :) с оговоркой ReceiveLength выдаст количество инфы во внутреннем буфере сокета и эту инфу ты можешь спокойно без блокировки потока считать, но байтом больше ты можешь встать в ожидание или сгенерировать ошибку сокета
Но


 
SpellCaster   (2006-07-10 14:20) [20]


> medved_68


> А событие ОНКОННЕКТ клиента привязал в нити???? Это если
> не в блоке.

А зачем? Оно же должно выполняться при коннекте, а коннекта у меня не происходит.


> Slym


> Если ошибка не вывалилась значит выполнилось.

К сожалению, нет. Active по-прежнему остается False, ничего не передается.


 
Сергей М. ©   (2006-07-10 15:02) [21]


> SpellCaster   (10.07.06 14:20) [20]



> Оно же должно выполняться при коннекте, а коннекта у меня
> не происходит


Событие OnConnect как раз и является фактом успешно установленного коннекта.


> ctive по-прежнему остается False


Значит режим - неблокирующий.


 
SpellCaster   (2006-07-10 15:26) [22]

ОнКоннект не вызывается. Сеодинения не происходит.

> Значит режим - неблокирующий.

А разве это св-во играет роль только в блоке?

Попробовал коннектиться так:
   fClient.Socket.Connect(fClient.Socket.SocketHandle);

ClientConnect выполняется, однако на сервере список соединений пуст (Server.Socket.ActiveConnections).

Можно, в принципе, соединяться из главного потока проги; просто как-то не хочется выносить это из кода потока. Да и просто неясно, почему не фурычит коннект из потока.


 
Ketmar ©   (2006-07-10 15:34) [23]

есть подозрение, что коннект долго устанавливается. а так как режим неблокирующий, то...


 
Сергей М. ©   (2006-07-10 15:37) [24]


> ОнКоннект не вызывается. Сеодинения не происходит


Если OnConnect не происходит, то должно произойти OnError, где как раз и можно выяснить причину отказа.


> Можно, в принципе, соединяться из главного потока проги


Так ты что, всю эту клиентскую петрушку в доп.потоке пытаешься сотворить ?
Вопрос - зачем ?

Разумеется, ни одно событие в доп.потоке не возникнет, пока ты не организуешь там цикл ожидания/выборки/диспетчеризации оконных сообщений !


 
SpellCaster   (2006-07-10 16:40) [25]

Ketmar, у меня сервер и клиент в одной проге, соединяются по 127.0.0.1. Задержек быть не должно вроде бы )). К тому же я ставил sleeP(2000) - та же шняга.

>Сергей М.

> Так ты что, всю эту клиентскую петрушку в доп.потоке пытаешься
> сотворить ?
> Вопрос - зачем ?

Потому что у меня должно быть несколько одновременных подключений к разным сервакам. Потоки должны будут принимать инфу и сливать ее в файлы. Вариант создавать несколько экземпляров сокет-клиентов в главном модуле и вешать на них события меня как-то не очень прельщает.


> Разумеется, ни одно событие в доп.потоке не возникнет, пока
> ты не организуешь там цикл ожидания/выборки/диспетчеризации
> оконных сообщений !

Не понял, при чем тут оконные сообщения? События вызываются в коде TCustomWinSocket-а, и им чихать на окна.

Причем мне-то они пока и не нужны! Я просто пытаюсь подключиться к серваку. Сервак у меня лежит визуально на форме, у него есть событие КлиентКоннект. При подключении из потока это событие не вызывается, а при подключении из кода основного модуля (в баттон.Онклик) - всё путём.


 
Сергей М. ©   (2006-07-10 16:53) [26]


> у меня должно быть несколько одновременных подключений к
> разным сервакам. Потоки должны будут принимать инфу и сливать
> ее в файлы


Все это с успехом реализуется в одном-единственном (основном) потоке.
Если , конечно же, на основной поток не возложены при этом какие-либо "обязанности", кроме интерактивного взаимодействия с юзером.


> Вариант создавать несколько экземпляров сокет-клиентов в
> главном модуле и вешать на них события меня как-то не очень
> прельщает


Ну и не вешай ! Но при этом придется задействовать блокирующий режим.
И "главный модуль" твой тут вообще ни причем.


> при чем тут оконные сообщения?


При том что в режиме ctNonBlocking Борландом задействуется асинхронная нотификация о событиях гнездового транспорта именно с использованием окон и оконных сообщений.


> Сервак у меня лежит визуально на форме


Безразлично где он "лежит".


> у него есть событие КлиентКоннект. При подключении из потока
> это событие не вызывается


Значит нет подключения. поэтому и не "вызывается".
Причины отказа ищи в параметре ErrorСode события TClientSocket.OnError (для режима ctNonBlocking) или в сообщении об исключении, возникшем при выполнении ClientSocket.Open (для режима ctBlocking)


 
medved_68 ©   (2006-07-10 17:05) [27]


> SpellCaster

А кто тебе мешает сделать коннект в главном потоке и по событию ОНКОННЕКТ прикрутить дополнительный поток работающий с этим сокетом (режим блокированный).


 
SpellCaster   (2006-07-10 18:16) [28]


> Ну и не вешай ! Но при этом придется задействовать блокирующий
> режим.
> И "главный модуль" твой тут вообще ни причем.

Да, я уже больше склоняюсь к блокирующему.


> При том что в режиме ctNonBlocking Борландом задействуется
> асинхронная нотификация о событиях гнездового транспорта
> именно с использованием окон и оконных сообщений.

А откуда ты это откопал? Я смотрел в исходниках, там вроде нет ничего связанного с окнами.


> Безразлично где он "лежит".

Это я к тому, что уж у него-то событие должно бы сработать. Но - не срабатывает.


> Значит нет подключения. поэтому и не "вызывается".
> Причины отказа ищи в параметре ErrorСode события TClientSocket.
> OnError (для режима ctNonBlocking) или в сообщении об исключении,
>  возникшем при выполнении ClientSocket.Open (для режима
> ctBlocking)

Так в том-то и весь фикус, что никаких ошибок не возникает!!! В противном случае я бы попробовал что-то разрулить, а тут просто выполняется строкча соединения, но с нулевым результатом, и все! Никаких событий не вызывается.


> А кто тебе мешает сделать коннект в главном потоке и по
> событию ОНКОННЕКТ прикрутить дополнительный поток работающий
> с этим сокетом (режим блокированный).

Ну в принципе, блокирующий и так нормально фурычит. А коннект... нужно предусмотреть возможность утсановки повторного подключения, если был обрыв связи. Логично это засунуть в код потока и постоянно проверять доступность канала. В принципе, можно извратиться и сделать проверку подключения в потоке, а сам коннект в главном модуле. Или попробовать просто synhronize(thread.connect).

Вообще, мне нет особой разницы, какого типа сокеты юзать. Просто блоки мне кажутся более естественными, да и отследить разрыв связи там проще: не поступает данных какое-то время - значит, обрыв.


 
Ketmar ©   (2006-07-10 19:09) [29]

>SpellCaster   (10.07.06 18:16) [28]
>  отследить разрыв связи там проще: не поступает данных какое-
> то время - значит, обрыв.

ещё проще. об обрыве расскажет сама recv() -- результатом. %-)

вообще, никогда не использовал неблокирующий режим. какой-то он, имо, неестественный.


 
Slym ©   (2006-07-11 07:29) [30]

Пользуешь неблокируемый режим который базируется на сообщениях, а где цикл выборки сообщений? нету... вот тебе сообщение и не приходит... т.е. сообщение об Active=true тебе не придет.

если уж подсел на блокирующий режим так и сиди на нем он проще в программировании


 
Slym ©   (2006-07-11 07:33) [31]

Slym ©   (11.07.06 7:29) [30]
а где цикл выборки сообщений?

Привентивный удар:
Цикл выборки сообщений главного потока не получит эти сообщения, т.к. клиентский сокет у тебя создан в контексте другого потока (хендл окна для сообщений тоже) то и сообщения будут направляться в дочерний поток.


 
Сергей М. ©   (2006-07-11 08:27) [32]


> SpellCaster   (10.07.06 18:16) [28]


> я уже больше склоняюсь к блокирующему


У этого режима так же как у неблокирующего есть свои преимущества и недостатки.
Выбор того или иного режима следует делать осознанно.


> откуда ты это откопал? Я смотрел в исходниках, там вроде
> нет ничего связанного с окнами


Сделай сквозной поиск по scktcomp.pas фразы "AllocateHwnd" и удивись.


> в том-то и весь фикус, что никаких ошибок не возникает


В неблок.режиме и не возникнет, потому что у тебя отсутствует цикл (см. [24], [29], [30]).


 
Slym ©   (2006-07-11 11:22) [33]

Сергей М. ©   (11.07.06 8:27) [32]
У этого режима так же как у неблокирующего есть свои преимущества и недостатки.

У неблокирующего, на мой взгляд, одни недостатки, а если не так, то почему в "сетевой" ОС linux нет неблокирующих сокетов?


 
Сергей М. ©   (2006-07-11 11:28) [34]


> почему в "сетевой" ОС linux нет неблокирующих сокетов?


В Линухе иной событийный механизм, нежели в Win32. Он базируется на т.н. "сигналах". Сокеты как таковые тут ни при чем.


> неблокирующего, на мой взгляд, одни недостатки


Позволю себе не согласиться с этим.


 
SpellCaster   (2006-07-11 15:39) [35]

Slym
Сергей М.

Я смотрел все статьи с Delphi World по этой теме, и нигде ничего не было про цикл выборки сообщений. Есть где-нибудь пример?


> Сделай сквозной поиск по scktcomp.pas фразы "AllocateHwnd"
> и удивись.

Мда... TCustomWinSocket фактически представляет собой окно...


> У этого режима так же как у неблокирующего есть свои преимущества
> и недостатки.
> Выбор того или иного режима следует делать осознанно.

А если можно, вкратце - какие? Просто они оба мне сейчас одинаковы, хотелось бы не ошибиться в выборе и уже определить, стоит ли мучить неблок дальше или остаться с блоком. Только, пожалуйста, не надо отсылать меня к каким-нибудь толстым книжкам и длинным статьям...


 
Сергей М. ©   (2006-07-11 15:47) [36]


> SpellCaster   (11.07.06 15:39) [35]



> нигде ничего не было про цикл выборки сообщений


Как думаешь, для чего нужен метод Application.Run ?


 
SpellCaster   (2006-07-11 17:40) [37]

Я имею в виду, применительно к сокетам.
А что, этот цикл обработки - по типу как в прогах на голом win API?


 
Slym ©   (2006-07-12 05:41) [38]

SpellCaster   (11.07.06 15:39) [35]
стоит ли мучить неблок дальше или остаться с блоком


Неблокирующие нотификация реализована на сообщениях окнам,
Эти сообщения может обрабатывать один единственный поток - главный поток программы, и доп. потоков не требуется. Все операции встают в очередь (очередь сообщений) т.к. обрабатываются одним потоком, отсюда - если попадется длительная операция подвиснит весь сервер, все другие клиенты.

Блокирующий режим может остановить выполнение потока, поэтому все блокирующие операции оборачиваются в отдельный поток, дабы не тормозить другие операции. Все операции выполняются в отдельных потоках, что не вызывает "подвис" основного потока так и других потоков. Все клиенты одновременно могут выполнять длительные операции.


 
Сергей М. ©   (2006-07-12 08:17) [39]


> SpellCaster   (11.07.06 17:40) [37]


> этот цикл обработки - по типу как в прогах на голом win
> API?


Именно так.


 
SpellCaster   (2006-07-12 12:54) [40]

ОК, буду юзать блоки. Всем спасибо за инфу!



Страницы: 1 2 вся ветка

Текущий архив: 2006.12.03;
Скачать: CL | DM;

Наверх




Память: 0.61 MB
Время: 0.057 c
15-1163342606
Legolas
2006-11-12 17:43
2006.12.03
А в Delphi 7 можно сделать так, чтоб мышь сама бегала и т д?


6-1153152312
cando
2006-07-17 20:05
2006.12.03
слежка за портом


15-1163285673
lookin
2006-11-12 01:54
2006.12.03
ISO - напомните плз, какой программой его можно превратить в AVI


15-1163567884
vajo
2006-11-15 08:18
2006.12.03
Dell вернула деньги за Windows поклоннику Linux


2-1163601511
term1t
2006-11-15 17:38
2006.12.03
FastReport