Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.07.2008, 23:04   #1
AlexandrY
 
Регистрация: 09.07.2008
Сообщений: 8
По умолчанию Разбирался с аналогичной проблемой.

Также с использованием Indy10 в RAD Studio 2007 сделал стресс тестер TCP соединений.
И клиент и сервер были на одном и том же компьюьтере.
Система: Win XP SP2 4-х ядерный пень и RAM 4 GB

До количества в 300 подключений все шло на ура.
На все 300 потоков памяти ушло несколько мегабайт (потоки сами могут регулировать свой стек, это опровергает байки про 1 M на поток )


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

Анализ кода Indy показал, что он интенсивно использует сервисы Delpfi для выделения памяти. И с учетом кривизны библиотек Delphi в многопоточной среде, надо думать многие проблемы Indy именно из-за памяти.

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

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

1. На что распростроняется это ограничение, на входящие или исходящие соединения, или и те и другие суммарно?

2. Можно ли это ограничение снять, например в реестре?

Использую: Delphi 7, IdTCPServer из Indy 10, Windows XP Pro Sp2, Pentium M64, RAM 2048Gb, без файла подкачки.

После запуска сервера и тестовой программки с клиентами: свободной памяти - полно, процессор загружен менее чем на 1%
AlexandrY вне форума Ответить с цитированием
Старый 09.07.2008, 23:58   #2
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
(потоки сами могут регулировать свой стек, это опровергает байки про 1 M на поток )
Не надо с серьёзным видом писать ерунду. К тому же, как видите, ТС умудрился запустить ~2000 потоков, а не 300.
B_N вне форума Ответить с цитированием
Старый 10.07.2008, 17:01   #3
AlexandrY
 
Регистрация: 09.07.2008
Сообщений: 8
По умолчанию Объясняю на пальцах

В дельфях Min Stack Size в линковщике указан $4000 по умолчанию
А криэйтор класса TThread вызывает BeginThread c размером стека равным 0.
Т.е. при создании потока в дельфях из класса TThread (а это и использует Indy) выделяется физически стек в $4000 байт как говорит линковщик по умолчанию.
Стек, конечно, может расти до мега, но это только в случае если юзер не совладает с рекурсией
Вообщем проблем с памятью для потоков нет.

Проблема в функциях Дельфи. Они нестабильны в многопоточной среде.
А траблы с GetMemory - научно установленный факт.

А свою прогу я гонял на разных компах. И получал разное количество тредов. К тому же надо умножать на 2 поскольку и стресс тестер и прога были на одном компе.
И просто создать треды с сокетами целью не было, все сокеты реально подключались и одновременно передавали данные в общую базу.



Цитата:
Сообщение от B_N Посмотреть сообщение
Не надо с серьёзным видом писать ерунду. К тому же, как видите, ТС умудрился запустить ~2000 потоков, а не 300.
AlexandrY вне форума Ответить с цитированием
Старый 10.07.2008, 17:50   #4
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

AlexandrY, если хотите, можем подискутировать об этом в другой теме. Создайте новую или попросим модератора раздела перенести крайние посты, поскольку явно отклоняемся от темы топика. Для начала могу сказать - не путайте выделенную память и зарезервированную.
B_N вне форума Ответить с цитированием
Старый 11.07.2008, 19:00   #5
AlexandrY
 
Регистрация: 09.07.2008
Сообщений: 8
По умолчанию

Да я уже с проблемой разобрался.
Прога создает 2000 сокетов менее чем за 1 сек через компоненты Indy.
Соответственно на тестовом компе появилось 4000 новых потоков.
Для моей задачи более чем достаточно.
На этот раз комп был скромнее, всего 1 Gb RAM-а и одноядерный проц.
C 4500 тредов операционка захватила всего 400 MB RAM-а.
Но если вы говорите что это не в тему, то наверно не буду рассказывать в чем была настоящая проблема в моем случае.


Цитата:
Сообщение от B_N Посмотреть сообщение
AlexandrY, если хотите, можем подискутировать об этом в другой теме. Создайте новую или попросим модератора раздела перенести крайние посты, поскольку явно отклоняемся от темы топика. Для начала могу сказать - не путайте выделенную память и зарезервированную.
AlexandrY вне форума Ответить с цитированием
Старый 12.07.2008, 00:52   #6
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Во-первых, спасибо за перенос темы, во избежание недоразумений уточню, что часть постов перенесена отсюда.

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Но если вы говорите что это не в тему, то наверно не буду рассказывать в чем была настоящая проблема в моем случае.
Конечно не в тему и что Вам мешает дать ответ в той теме, если он относится к тому вопросу, но Вы же начали говорить про проблемы борландовского менеджера памяти, весьма глючного, соглашусь, по крайней мере на прежних версиях, и про то, что 1 мег стэка на поток - это "байки". А это, смею Вас уверить, никакие не байки, а совершенно официальная информация: http://msdn.microsoft.com/en-us/libr...74(VS.85).aspx
Дело здесь вот в чём. Если Вы запустите вот такую программу:
Код:
#include <stdio.h>
#include <windows.h>
#include <winnt.h>

HANDLE hStartEvent = NULL;

DWORD WINAPI ThreadProc(int iThread)
{
	printf("Thread : %8d, Stack : %08p, TEB : %08p\n", iThread, &iThread, NtCurrentTeb());
	SetEvent(hStartEvent);
	Sleep(INFINITE);
	return 0;
}

int main()
{
	hStartEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	for(int i = 0; i < 10000; i++)
	{
		if (! CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, (LPVOID)i, 0, NULL)) break;

		WaitForSingleObject(hStartEvent, INFINITE);
	}
	CloseHandle(hStartEvent);
	
	puts("press enter...");

	getchar();
	return 0;
}
На всякий случай, она же на дельфи:

Код:
program stacks;

{$APPTYPE CONSOLE}

uses
    windows, SysUtils;


{$IFNDEF STACK_SIZE_PARAM_IS_A_RESERVATION}
//#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
const
    STACK_SIZE_PARAM_IS_A_RESERVATION : DWORD = $00010000;
{$ENDIF}

var
    hStartEvent : THANDLE = 0;
    i           : integer;
    thid        : cardinal;

function NtCurrentTeb() : pointer; stdcall; external 'ntdll';

function ThreadProc(iThread : cardinal): DWORD; stdcall;
begin
    writeln(format('Thread : %8d, Stack : %08p, TEB : %08p',
                [iThread, @iThread, NtCurrentTeb()]));
	SetEvent(hStartEvent);
	Sleep(INFINITE);
    result := 0;
end;

begin
	hStartEvent := CreateEvent(0, FALSE, FALSE, 0);
	for i := 0 to 10000 do begin
		if (CreateThread(nil, 0, @ThreadProc, POINTER(i), 0, thid) = 0) then break;

		WaitForSingleObject(hStartEvent, INFINITE);
	end;
	CloseHandle(hStartEvent);

	writeln('press enter...');

	readln;
end.
то увидите вот примерно вот такую картину:
Цитата:
.........
.........
Thread : 2003, Stack : 7F19FFBC, TEB : 7F6E6000
Thread : 2004, Stack : 7F29FFBC, TEB : 7F6E5000
Thread : 2005, Stack : 7F39FFBC, TEB : 7F6E4000
Thread : 2006, Stack : 7F49FFBC, TEB : 7F6E3000
Thread : 2007, Stack : 7F59FFBC, TEB : 7F6E2000
Thread : 2008, Stack : 7F69FFBC, TEB : 7F6E1000
press enter...
То есть, как видите, стэки каждого потока начинаются ровно через мегабайт и удалось создать только около двух тысяч потоков. При этом совершенно неважно, сколько памяти установлено, хоть 64 Mb - на мегабайт различаются именно адреса стэков. Тот самый параметр Min Stack Size вовсе не устанавливает размер стэка по умолчанию, его задаёт Max Stack Size, при этом на каждый поток резервируется (MEM_RESERVE) <Max Stack Size> байт виртуальной памяти, но при этом фиксируется (MEM_COMMIT) только <Min Stack Size> байт, ч учетом 64-х килобайтной грануляции. Стэк вовсе не растёт, а лишь "довыделяется" в пределах <Max Stack Size>. С другой стороны, мы можем, например, написать так:
Код:
if (CreateThread(nil, 512*1024, @ThreadProc, POINTER(i), STACK_SIZE_PARAM_IS_A_RESERVATION, thid) = 0) then break;
и сразу увидим, что теперь в 2 Gb адресного пространства "влезает" примерно 4000 потоков. Можно ли это назвать выходом из положения? Если преследуются чисто экспериментальные цели, то да. А если мы собираемся построить крупный сервер на большое число коннектов, то однозначно - ни в коем случае. Потому, что куча процессорного времени пойдёт исключительно на переключение контекстов этих тысяч потоков между собой и в ядро и обратно, потому, что мы вынуждены будем выделить может и не очень страшный по нынешним меркам, но во много раз больший, чем у других процессов объём резидентного пула, который ещё ко всему же очень быстро фрагментируется, и рискуем закончить блюскрином, потому что рискуем устроить себе очень большие проблемы с синхронизацией этих потоков. Для этих целей есть много асинхронных способов ввода/вывода, в том числе и с сокетов, которыйе позволяют обойтись разумным, в 2-3, количеством ниток.
B_N вне форума Ответить с цитированием
Старый 12.07.2008, 20:53   #7
AlexandrY
 
Регистрация: 09.07.2008
Сообщений: 8
По умолчанию

Жаль, этим вы насолили только навичку Vynt с которым я и хотел общаться.
Теперь ему придется рыться в темах чтобы найти ответ на свой вопрос, если он вообще знает ухватки местных модераторов.
И совершенно не собирался с вами дискутировать по поводу многопоточности.

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









Цитата:
Сообщение от B_N Посмотреть сообщение
Во-первых, спасибо за перенос темы, во избежание недоразумений уточню, что часть постов перенесена отсюда.



Конечно не в тему и что Вам мешает дать ответ в той теме, если он относится к тому вопросу, но Вы же начали говорить про проблемы борландовского менеджера памяти, весьма глючного, соглашусь, по крайней мере на прежних версиях, и про то, что 1 мег стэка на поток - это "байки". А это, смею Вас уверить, никакие не байки, а совершенно официальная информация: http://msdn.microsoft.com/en-us/libr...74(VS.85).aspx
Дело здесь вот в чём. Если Вы запустите вот такую программу:
Код:
#include <stdio.h>
#include <windows.h>
#include <winnt.h>

HANDLE hStartEvent = NULL;

DWORD WINAPI ThreadProc(int iThread)
{
	printf("Thread : %8d, Stack : %08p, TEB : %08p\n", iThread, &iThread, NtCurrentTeb());
	SetEvent(hStartEvent);
	Sleep(INFINITE);
	return 0;
}

int main()
{
	hStartEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	for(int i = 0; i < 10000; i++)
	{
		if (! CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, (LPVOID)i, 0, NULL)) break;

		WaitForSingleObject(hStartEvent, INFINITE);
	}
	CloseHandle(hStartEvent);
	
	puts("press enter...");

	getchar();
	return 0;
}
На всякий случай, она же на дельфи:

Код:
program stacks;

{$APPTYPE CONSOLE}

uses
    windows, SysUtils;


{$IFNDEF STACK_SIZE_PARAM_IS_A_RESERVATION}
//#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
const
    STACK_SIZE_PARAM_IS_A_RESERVATION : DWORD = $00010000;
{$ENDIF}

var
    hStartEvent : THANDLE = 0;
    i           : integer;
    thid        : cardinal;

function NtCurrentTeb() : pointer; stdcall; external 'ntdll';

function ThreadProc(iThread : cardinal): DWORD; stdcall;
begin
    writeln(format('Thread : %8d, Stack : %08p, TEB : %08p',
                [iThread, @iThread, NtCurrentTeb()]));
	SetEvent(hStartEvent);
	Sleep(INFINITE);
    result := 0;
end;

begin
	hStartEvent := CreateEvent(0, FALSE, FALSE, 0);
	for i := 0 to 10000 do begin
		if (CreateThread(nil, 0, @ThreadProc, POINTER(i), 0, thid) = 0) then break;

		WaitForSingleObject(hStartEvent, INFINITE);
	end;
	CloseHandle(hStartEvent);

	writeln('press enter...');

	readln;
end.
то увидите вот примерно вот такую картину:


То есть, как видите, стэки каждого потока начинаются ровно через мегабайт и удалось создать только около двух тысяч потоков. При этом совершенно неважно, сколько памяти установлено, хоть 64 Mb - на мегабайт различаются именно адреса стэков. Тот самый параметр Min Stack Size вовсе не устанавливает размер стэка по умолчанию, его задаёт Max Stack Size, при этом на каждый поток резервируется (MEM_RESERVE) <Max Stack Size> байт виртуальной памяти, но при этом фиксируется (MEM_COMMIT) только <Min Stack Size> байт, ч учетом 64-х килобайтной грануляции. Стэк вовсе не растёт, а лишь "довыделяется" в пределах <Max Stack Size>. С другой стороны, мы можем, например, написать так:
Код:
if (CreateThread(nil, 512*1024, @ThreadProc, POINTER(i), STACK_SIZE_PARAM_IS_A_RESERVATION, thid) = 0) then break;
и сразу увидим, что теперь в 2 Gb адресного пространства "влезает" примерно 4000 потоков. Можно ли это назвать выходом из положения? Если преследуются чисто экспериментальные цели, то да. А если мы собираемся построить крупный сервер на большое число коннектов, то однозначно - ни в коем случае. Потому, что куча процессорного времени пойдёт исключительно на переключение контекстов этих тысяч потоков между собой и в ядро и обратно, потому, что мы вынуждены будем выделить может и не очень страшный по нынешним меркам, но во много раз больший, чем у других процессов объём резидентного пула, который ещё ко всему же очень быстро фрагментируется, и рискуем закончить блюскрином, потому что рискуем устроить себе очень большие проблемы с синхронизацией этих потоков. Для этих целей есть много асинхронных способов ввода/вывода, в том числе и с сокетов, которыйе позволяют обойтись разумным, в 2-3, количеством ниток.
AlexandrY вне форума Ответить с цитированием
Старый 13.07.2008, 01:00   #8
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Жаль, этим вы насолили только навичку Vynt с которым я и хотел общаться.
Предоставьте это решать ему самому. Общаться Вам никто не запрещает - общайтесь по теме, или создавайте новую, какие проблемы? Я пока не видел от Вас конкретных советов ему, и ничего нового, чего не было бы уже сказано в той теме. Только рассуждения по поводу борландовского MM и обвинения в "байках".

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Теперь ему придется рыться в темах чтобы найти ответ на свой вопрос, если он вообще знает ухватки местных модераторов.
Выбирайте выражения, AlexandrY И кто Вам сказал, что он не получил ответ на свой вопрос?

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
И совершенно не собирался с вами дискутировать по поводу многопоточности.
Вас никто не заставляет.

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Повторяю, никаких проблем большое количество потоков в WinXP не представляет, а то что 1 Meg чистая байка подтверждает ваша же ссылка.
Просто как факт вам покажу без комментариев несколько скриншотов:
...........................
Внимательно читайте то, что Вам пишут. И ту тему, кстати, тоже прочитайте. Там было сказано, что причина того, что не получается создать более 2000 потоков - мегабайт стэка на поток по умолчанию. Скриншоты Ваши, к сожалению, никакого интереса не представляют, можно запустить и 20 тысяч потоков. Как я уже писал выше - это очень плохой путь.
B_N вне форума Ответить с цитированием
Старый 13.07.2008, 02:15   #9
AlexandrY
 
Регистрация: 09.07.2008
Сообщений: 8
По умолчанию

Вот тока не надо... "По умолчанию" сказал я с принципиальным уточнением, что по умолчанию конкретного линкера. А MSDN таким линкером по умолчанию считает Visual Studio. Но в общем случае другому линкеру никто не запрещает иметь другую цифру по умолчанию. Так что байка она и есть байка
Но я вижу с вами можно иметь дело.
Вы уже категорично не настаиваете на скупых цифрах типа на более 2 тыс. или не более 4 тыс.
Уже и 20 тыс. оказывается можно. А нам больше и не надо. А если что, то переходим на следующую Ethernet карту и организуем новый процесс и опять назначаем в десяток тысяч тредов. Какие проблемы?
Скриншот я показал для того чтобы не молоть по пусту воду о том как треды занимают ресурсы проца.
Фиберы в этом плане ничуть не лучше.
И тредам и фиберам одинаково приходится сохранять контекст процессора. Т.е. накладные на переключение процессов будут одинаковые.
Причин для какой-то фрагментации чего-либо не вижу. Проблемы синхронизации тоже выглядят надуманными.
Но если делать все сокеты в одном треде то вынуждены будете мучительно делать все тот же самопальный кольцевой планировщик, и ради чего?
Просто потому что боимся тредов?

Так в чем там плохой путь с тредами?

Писать консольные процедурки не обязательно. Просто на пальцах, на уровне идей. Хорошую идею нетрудно и самому проверить.




Цитата:
Сообщение от B_N Посмотреть сообщение

Внимательно читайте то, что Вам пишут. И ту тему, кстати, тоже прочитайте. Там было сказано, что причина того, что не получается создать более 2000 потоков - мегабайт стэка на поток по умолчанию. Скриншоты Ваши, к сожалению, никакого интереса не представляют, можно запустить и 20 тысяч потоков. Как я уже писал выше - это очень плохой путь.
AlexandrY вне форума Ответить с цитированием
Старый 13.07.2008, 02:43   #10
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Вот тока не надо... "По умолчанию" сказал я с принципиальным уточнением, что по умолчанию конкретного линкера. А MSDN таким линкером по умолчанию считает Visual Studio. Но в общем случае другому линкеру никто не запрещает иметь другую цифру по умолчанию. Так что байка она и есть байка
Это ставится для любого линкера.

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Но я вижу с вами можно иметь дело.
Я польщён.

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Вы уже категорично не настаиваете на скупых цифрах типа на более 2 тыс. или не более 4 тыс.
А где я на этом настаивал? Выше я привёл код, который позволяет при определённой настройке их "генерировать"...

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Уже и 20 тыс. оказывается можно. А нам больше и не надо. А если что, то переходим на следующую Ethernet карту и организуем новый процесс и опять назначаем в десяток тысяч тредов. Какие проблемы?
Вы это можете назвать надёжным сервером? Смысл этой затеи? Достать правой ногой левое ухо? В том топике Vynt, за которого Вы так беспокоились, столкнулся с вполне конкретной проблемой, взгляните, кстати, в чём она заключается, особенно когда он переживает за то, что придётся её переложить на энд-юзера. Если он принесёт такое "решение" с десятком процессов и тысячами потоком (представьте, кстати, что придётся выделить в одном из этих процессов мег эдак 50 памяти - а её уже нету - она вся ушла на стэки.), я уверен - если с и не выгонят с работы, писать сложные вещи больше не доверят.

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Скриншот я показал для того чтобы не молоть по пусту воду о том как треды занимают ресурсы проца.
Затраты диспетчера задач (именно диспетчера задач, а не приложения taskman.exe, здесь не видны. [/QUOTE]

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Фиберы в этом плане ничуть не лучше.
И тредам и фиберам одинаково приходится сохранять контекст процессора. Т.е. накладные на переключение процессов будут одинаковые.
Я и не говорил, что лучше.

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Причин для какой-то фрагментации чего-либо не вижу.
Не "чего-либо", а Non Paged Pool. Причины? А обычные причины для фиксированного на одном месте объема памяти, в котором постоянно хаотически будут выделяться и удаляться тысячи блоков. Думаете, продержится такой "сервер" хотя бы неделю?

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Проблемы синхронизации тоже выглядят надуманными.
Всё выглядит надуманным, пока мы с этим не столкнулись.

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Но если делать все сокеты в одном треде то вынуждены будете мучительно делать все тот же самопальный кольцевой планировщик, и ради чего?
Позвольте, какой планировщик? Простой цикл с четырьмя-пятью вызовами внутри?

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Просто потому что боимся тредов?
Нет, не боимся. Когда они нужны и полезны - используем, и другим советуем. Когда их применение по принципу "лишь бы были" грозит построением неуправляемого чудовища - берём карандаш, если нужно, документацию и аккуратно проектируем.

Цитата:
Сообщение от AlexandrY Посмотреть сообщение
Так в чем там плохой путь с тредами?

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

-----------------------------

Да, ещё, насчёт "по умолчанию". Не надо играть в слова. Не стоит брать куски других постов, адресованных другим участникам, и строить на них свои доводы.

Последний раз редактировалось B_N; 13.07.2008 в 02:47.
B_N вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
многопоточность в Delphi xakkkkker Свободное общение 12 13.08.2010 18:52
Многопоточность Indy AVer Работа с сетью в Delphi 14 14.02.2009 22:10
Кодировка в приложениях Horror Общие вопросы .NET 3 16.04.2008 14:23
По поводу зациты от DoS в сетевых приложениях Delphi... dukie Работа с сетью в Delphi 2 30.12.2007 22:37