Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

WinSock + Threads! [D7, WinXP]


Страницы:   1 2

Nigger ©   (2003-04-27 19:09:00) 

Мастера... у меня большая проблемма! Пишу программу клиент с WinSock"ом и потоками... если делаю чтоб несколько потоков было,то на вторые пакеты ответ с сервера не идет (создается впечатление, что это один сокет с N-м количеством одинаковых пакетов - то есть все сокеты работают как один "большой") Может все дело в блокированых и неброкированых сокетах или потоках???
Как вообще реализовать многопоточное соединение клиента на WinSock???
И ещё: прога ругается что OutOfMemory - но это похоже, что с другим связано. И про recv хотел ещё спросить... что за странный тип переменной там используется - может я его как то не правильно использую? Помогите разобраться!

var
Buff: pchar;
z: string;

GetMem(Buff,size);
FillChar(Buff[1],size,0);
ret:=recv(S,Buff^,size,0);
z:=buff;
FreeMem(Buff, size);


Digitman   (2003-04-29 08:39:00) [21]


> Nigger


Под "клиентом" я понимаю некое гнездо, созданное процессом клиентского приложения и установившее соединение с гнездом, созданным процессом серверного приложения

Ты спросил :

> Как вообще реализовать многопоточное соединение клиента
> на WinSock


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


> как тогда бывают такие программы


Это - совершенно иной вопрос с иным контекстом !


> многопоточного клиента к pop3 серверу!


в процессом кл.приложения создается N код.потоком, в ходе работы каждого из которых создается ОТДЕЛЬНОЕ гнездо (ассоциированное с отдельным код.потоком) и устанавливается соединение с ОТДЕЛЬНЫМ гнездом сервера


Alex Konshin   (2003-04-29 05:29:00) [22]

2Nigger: делай как я сказал. В режиме overlapped ты можешь запускать несколько операций одновременно (хоть с одним сокетом, хоть с несколькими). Если же еще и грамотно организовать цикл ожидания-обработки, то вообще может и не понадобиться несколько нитей, ну или просто имей пул нитей и одну нить, которая ждет завершения операций и сразу же отдает полученное событие первой свободной нити. Короче, все на твое усмотрение, как сделаешь так и будет. На мой взгляд модель в Winsock2 даже проще и понятнее, забудь о блокирующем режиме как о кошмарном сне.


Alex Konshin   (2003-04-29 05:15:00) [23]


> 2Alex Konshin © (28.04.03 07:41)
> ИМХО не в тему, вопрошающий пытается работать в блокирующем
> режиме, судя по всему, раз несколько потоков ему надо

Как это не в тему? Вот как раз-таки под Winsock 1.x пытаться работать в нескольких потоках и есть извращение.
И к тому же winsock 1.x под NT+ реализован как wrapper вокруг Winsock2. Зачем вам лишний слой, который еще и не добавляет, а уменьшает функциональность?


Nigger   (2003-04-28 23:59:00) [24]

2Alex Konshin again:
Хоть в том, что ты сказал разобрался...огромное спасибо....
Кому надо почитать про это - вот страничка:
http://www.sources.ru/cpp/cpp_network_evets_winsock2.shtml


Nigger   (2003-04-28 23:49:00) [25]

Кхм... и ещё, как я понял для многопоточности нужен блокирующий режим. так ли это? если так, то как его на winsock включить, или он по дефолту поставлен??? (Страрые функции WSAiSBlocking Hook etc уже устарели)


Nigger   (2003-04-28 23:45:00) [26]

2Polevi: я пытаюсь понять на чем это вобще можно сделать и как это будет работать - пока ниначем не получается.
2Digitman:
< Как вообще реализовать многопоточное соединение клиента
< на WinSock???
> Никак.
Вот тут я совсем не знаю что сказать, а как тогда бывают такие программы??? Например tetroPWD... или есть в статье "взлом мыла" (кстати почти везде валяется)исходник на делфи многопоточного клиента к pop3 серверу! - что самое странное с этим кодом твариться тоже самое что и с моим - все работает как один сокет....
Не знаю что и делать.
2Alex Konshin:
мысль об этом - что нужен winsock2, просто я раньше думал что я его и использую....
И ещё один вопрос: для создания такой программы нужно делать привязку данного сокета к адресу (bind etc)????


Digitman   (2003-04-28 10:10:00) [27]

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


Digitman   (2003-04-28 10:07:00) [28]


> Как вообще реализовать многопоточное соединение клиента
> на WinSock???


Никак.
Вызов Winsock-ф-ций для управления гнездовым транспортом допускается в каждый момент времени только в контексте одного кодового потока.

попросту говоря, та же упомянутая ф-ция recv(), будучи вызванная трэдом 1, не должна вызываться никаким другим трэдом до момента возврата ф-цией recv() управления вызвавшему ее трэду 1


Polevi   (2003-04-28 09:44:00) [29]

2Alex Konshin © (28.04.03 07:41)
ИМХО не в тему, вопрошающий пытается работать в блокирующем режиме, судя по всему, раз несколько потоков ему надо


Alex Konshin   (2003-04-28 07:41:00) [30]

В Winsock 1.x события приходят через очередь сообщений Windows. Если у тебя несколько потоков, то эти потоки тоже должны обрабатывать эти сообщения. TThread их просто игнорирует (может я и не прав, мне сейчас лень глядеть в код).

На мой взгляд, гораздо проще использовать Winsock2, особенно в многопоточных приложениях.
Работай через функции WSA* ассинхронно (overlapped и/или completion routines) и жди событий с помощью WSAWaitForMultipleEvents - так намного понятнее, когда работаешь в нескольких потоках.
Например, используй WSARecv, в параметре lpOverlapped передаешь адрес структуры, в поле hEvent которой вписываешь handle события. Потом жди этого события по WSAWaitForMultipleEvents.
Можешь еще в completion routine выставлять какое-нибудь событие, это тоже премлемое решение. А остальное - это уж как тебе нравиться и как в задаче требуется, много разных вариантов можно придумать.

Про функции читай MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/windows_sockets_start_page_2.asp
Например, для WSAWaitForMultipleEvents:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsawaitformultipleevents_2.asp

Чтоб работать с Winsock2 в Delphi бери мой юнит с моего сайта:
http://home.earthlink.net/~akonshin/index.htm
В Delphi7 (точнее, в Indy) есть IdWinsock2.pas, это тоже подойдет, но реально это чуть урезанный мой юнит (посмотри копирайт).


Nigger   (2003-04-28 00:12:00) [31]

Спасибо конечно, но ситуация никаким макаром не изменилась(Опять какую то ошибку выдает насчет pchar)... и меня по прежнему интересует вопрос насчет сокетов (см. выше)


Illusion   (2003-04-27 21:08:00) [32]

всё что ние, после бреда - меня прогючила, не обращать внимание :)


Illusion   (2003-04-27 21:03:00) [33]

Pchar = pointer char.
Аналог char* в С и С++.
историческая справка: строки бывают двух типов. В паскале широко применятся Pascal стринг. Это когда в первом (читай нулевом) байте записанна длинна строки, а ждалее идёт сама строка. D C++ (вернее в билдере) сия фигня реализовнна в классе AnsiString, который эмулирует паскаль строчки. Но в С/С++ широко применяется Pointer String. Это когда строка начинается с нулевого символа. И символ с кодом 0 означает конец строки.
т.к. все функции в винсоке заточенны под С/С++, то соответвестнно возращают значение в используемых парамерах. Чё тебе делать? вот что...

var
Buff: pchar;
z: string;
ret:integer;

GetMem(Buff,size);
buff[0] := 0;
ret:=recv(S,Buff^,size,0);
buff[ret] := 0;
z:=buff;
FreeMem(Buff, size);

ljk;yjvar
Buff: pchar;
z: string;

GetMem(Buff,size);
FillChar(Buff[1],size,0);
ret:=recv(S,Buff^,size,0);
z:=buff;
FreeMem(Buff, size);

должно работать.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо