[C#] Сокеты и нити

Eugenia_2005

1) что такое нить, в с мысле чем она отличается от параллельных процессов и что делает ThreadPool.QueueUserWorkItem(new WaitCallback(... чем отличается от fork
справку мсднную читал и не нашел этих вещей
2) нужно ожидать подключения от клиента и при этом чтобы не висло приложение (как это от блокирующего Accept'а)
- если сделать это другой нити (после ThreadPool.QueueUserWorkItem то как закрыть тогда сокет пока он в Accept'е? socket.close выдает исключение если не было ни одного подключения
- если сделать сокет неблокирующим ( socket.Blocking = false; то close в главной нити тоже выдает исключение по поводу "A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied"

Dasar

> что делает ThreadPool.QueueUserWorkItem(new WaitCallback(...
Берут нить(поток/тред) из пула потоков - и выполняет в нем переданный делегат.
> как закрыть тогда сокет
попробуй Dispose

Eugenia_2005

>попробуй Dispose
'System.Net.Sockets.Socket.Dispose(bool)' is inaccessible due to its protection level
>Берут нить(поток/тред) из пула потоков - и выполняет в нем переданный делегат.
эта нить при этом создается наподобие fork или она уже есть в этом пуле?
когда делегат завершит работу нить кончается или что с ней происходит?

frant5

вроде она уже есть в пуле
и вроде остается

Dasar

> 'System.Net.Sockets.Socket.Dispose(bool)' is inaccessible due to its protection level
тебе нужен, который просто Dispose, без параметров
> эта нить при этом создается наподобие fork или она уже есть в этом пуле?
уже создана
> когда делегат завершит работу нить кончается или что с ней происходит?
возвращается обратно в пул

Eugenia_2005

>тебе нужен, который просто Dispose, без параметров
так и вызываю, "sock.Dispose;" , выходит эта ошибка
может сокет другой?

Dasar

тогда напиши так:
IDisposable)socket).Dispose;

daru

В msdn есть пример работы с асинхронными сокетами (BeginAccept / EndAccept, если мне память не изменяет). Думается, что этот пример решит твою проблему.

Eugenia_2005

:
An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in system.dll
Additional information: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied

Eugenia_2005

да, пытался, но в этом случае Close тоже вызывает исключение то же самое причем

Dasar

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

voronina

fiber - нет переключения между задачами: программная абстракция позоволяющая реализовать многопоточноть ипользуя один процессор
thread - есть свой стек (следовательно не статические переменные не являются общими для всех потоков) при обращении к статическим данным надо проявлять осторожность: использовать семафоры, mutex, lock (в C#) это самый обычной способ сделать многопоточное приложение здесь наибольшая скорость передачи данных между выполняющимися потоками: (залочил.записал.отлочил). довольно часто используется 2-х поточная модель: 1)длительная обработка данных 2) пользовательский интерфейс (в простейшем случае кнопка выйти)
process - длительное переключение между процессами дядя Рихтер даже по-моему приводит в тактах что сколько приблизительно занимает. Что дает использование нескольких просессов: прежде всего это повышение устойчивости програмной системы: программа может состоять из 2-частей: стабильный просесс, обрабатывающий данные, и графический интерфейс с глючной библиотекой: при смерти родительского процесса детей обычно не давят.
если имеется в виду unix fork то последний должен при вызове полностью скопировать память и сделать точною копию процесса (за исключением переменной, которую надо вернуть)
pooling: если создание и удаление занимает много времени, то мы создаем сразу штук 20 и не удаляем относится к дескрипторам файлов, соединениям с базой данных, потокам и др.
Неблокирующие вызовы для работы с сокетами и файлами: обычно сценарий: запустить операцию, сделать свое дело, спать пока операция не закончится
если тебе надо сокет для listen то см. msdn:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconUsingNon-BlockingServerSocket.asp
если для клиетна, то зачем создавать и удалять много сокетов?
З.Ы. каждый программист на VB 6.0 должен знать WinApi

Eugenia_2005

хм да, это было во время sock.Shutdown(SocketShutdown.Both); - отладчик показывал следующую строку для выполнения, коей был Close
если убрать этот вызов, получается такое исключение, уже из-за Close, но в другой нити, которая ждет подключения клиента - после вызова CLose, я так понимаю во время вызова "s.EndAccept(ar);" :
An unhandled exception of type 'System.InvalidOperationException' occurred in system.dll
Additional information: AcceptCallback
Может быть стоит перед тем как закрывать сокет проверить, есть ли хоть одно клиентское подключение, и если нет, то Close не вызывать?
но как это сделать найти не могу

voronina

у тебя выше приведеннй msdn'новский пример не работает?

Vladislav177Rus

каждый программист на VB 6.0 должен знать WinApi
Не только должен, но и вынужден

Eugenia_2005

спасибо за ссылку на этот пример, написано хорошо
попробовал, но снова после listener.Close; во второй слушающей нити выкидывается то же исключение :
An unhandled exception of type 'System.InvalidOperationException' occurred in system.dll
Additional information: AcceptCallback

Eugenia_2005

короче спрошу проще
как заставить сокет прекратить слушать?
особенно если нет еще клиентских подключений

freezer

на такие вопросы интереснее ответы самому искать...
Вот, рекомендую программку: http://www.aisto.com/roeder/dotnet/Download.aspx?File=Reflector

Eugenia_2005

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

freezer

вполне... переводит сборки в нет-овские языки (c#, например включая системный. Можешь легко посмотреть что нужный тебе класс использует и с какими параметрами вызывает

Eugenia_2005

ой
типа скомпиленный код переводит обратно в язык высокого уровня?
то есть можно код системных библиотек смотреть похоже

Eugenia_2005

так все же
как заставить сокет прекратить слушать?

freezer

да, причем там довольно удобная навигация по коду

freezer

попробуй socket.Shutdown(SocketShutdown.Both);
а если не поможет -
try
{
socket.Close;
}
catch(SocketException ex) {}

Eugenia_2005

>socket.Shutdown(SocketShutdown.Both);
да, пробовал, в слушающей нити после этого ведь еще происходят попытки принять данные, и снова исключение :
An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in system.dll
Additional information: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
может попробовать эту слушающую нить прибить?

freezer

ЛОЛ
Вот что из System.Net.Sockets.Socket выковырял:
public void Close
{
IDisposable) this).Dispose;
}

Eugenia_2005

да, я тоже на это наткнулся хе хе

freezer

лучше ловить исключение. Если ты прибьешь поток - то все равно вызовется тот же Dispose, только исключение ты уже не увидишь.

rosali

эта нить ... уже создана
Это так и есть, но честно говоря какое-то стремное решение... Если пул весь израсходован, можно было бы заводить новые треды, но этот самый ThreadPool вместо этого ждет, когда старые завершатся. Так же в дэдлок можно угодить, то есть треды, исполняющиеся сейчас, будут ждать тредов из очереди, а те никогда не начнутся. Или я чего-то гоню?

Marinavo_0507

> то есть треды, исполняющиеся сейчас, будут ждать тредов из очереди
не делай так (c)

Dasar

> Если пул весь израсходован, можно было бы заводить новые треды
ThreadPool - предназначен для выполнения коротких операций в отдельных потоках.
> Так же в дэдлок можно угодить, то есть треды, исполняющиеся сейчас, будут ждать тредов из очереди, а те никогда не начнутся. Или я чего-то гоню?
Для таких операций необходимо использовать свои потоки, а не потоки из ThreadPool.

bastii

я в сокетах не бум-бум, но может там асинхронные вызовы спасут от создания потоков (а уже про это писали )

Eugenia_2005

что такое свои потоки?

bastii

ну берешь и запускаешь на каждый конект или что у тебя отдельный поток, который сам ручками создаешь и запускаешь (а не из пула берешь)

Dasar

> что такое свои потоки?

Thread thread = new Thread(..);
thread.Start;
Оставить комментарий
Имя или ник:
Комментарий: