Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/55: Рейтинг темы: голосов - 55, средняя оценка - 4.55
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
1

Как прекратить Socket.Accept()

14.05.2013, 21:23. Показов 10210. Ответов 24
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте! В коде вызываю Socket.Accept() и, в некоторых ситуациях, его нужно прекратить, но если вызываю Socket.Close() - выбрасывается исключение. Что делать?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.05.2013, 21:23
Ответы с готовыми решениями:

Как прекратить выполнение асинхронного метода
Есть форма. По событию mouseUp исполняется следующий код: _isDragging = false; if...

Как прекратить Session переменную?
Можно ли прекратить принудительно конкретную Session переменную? Например имеется SessionID:...

Остановить socket.Accept() внутри блока while который находится внутри потока
Сам код using System; using System.IO; using System.Collections.Generic; using...

После Socket.Accept() зависает приложение
После строки Socket.Accept() зависает приложение ,я знаю что этот метод останавливает выполнение...

24
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
14.05.2013, 23:05 2
поймать исключение и заглушить
1
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
15.05.2013, 02:39  [ТС] 3
Неужели мелкософтовци ничего не придумали красивее?
0
21 / 20 / 3
Регистрация: 08.12.2012
Сообщений: 92
15.05.2013, 10:05 4
Socket.Disconnect() же
1
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
15.05.2013, 12:38  [ТС] 5
Цитата Сообщение от Crash94 Посмотреть сообщение
Socket.Disconnect()
Он тоже выбрасывает исключение.
0
21 / 20 / 3
Регистрация: 08.12.2012
Сообщений: 92
15.05.2013, 13:25 6
Цитата Сообщение от body90 Посмотреть сообщение
Он тоже выбрасывает исключение.
Очень странно... Сейчас пишу свой чат на сокетах, отсоединяюсь через Disconnect и ничего не выбрасывается. Может, вы случайно отсоединяете неподключенный сокет?
Может, так будет работать
C#
1
2
            
if(Socket.Connected)Socket.Disconnect(false);
Добавлено через 15 минут
А, это я не так понял вопрос.
1
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
15.05.2013, 14:17  [ТС] 7
Цитата Сообщение от Crash94 Посмотреть сообщение
А, это я не так понял вопрос.
Да) Мне нужно не разорвать соединение, а завершить ожидание нового подключения.
0
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 13
26.02.2014, 13:03 8
Да у меня такая же хрень, процесс остаётся висеть.
0
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
26.02.2014, 13:18  [ТС] 9
Вот именно. Я так и не нашел, как остановить ожидание подключения или входящих данных. Только таймаутом в цикле - но это же не есть гуд.
0
155 / 155 / 30
Регистрация: 19.10.2009
Сообщений: 319
26.02.2014, 14:16 10
Может, лучше проверять свойство Available, прежде чем делать Accept()? Типа если есть данные, то он не будет застревать на Accept'е, а если нет - вызывать Thread.Sleep на какое-то время и потом вновь проверять это свойство. А при каждом таком проходе можно и проверять тот факт, что нужно завершать процесс, а не ждать новых данных.

А события, к сожалению, здесь быт не может - winsock32.dll не имеет callback для socket'а о приходе новых данных.
1
99 / 39 / 12
Регистрация: 30.01.2011
Сообщений: 129
26.02.2014, 15:12 11
А почему, если не секрет не юзаете socket.BeginAccept()?
1
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
26.02.2014, 19:21  [ТС] 12
Цитата Сообщение от Ilya81 Посмотреть сообщение
Может, лучше проверять свойство Available, прежде чем делать Accept()? Типа если есть данные, то он не будет застревать на Accept'е, а если нет - вызывать Thread.Sleep на какое-то время и потом вновь проверять это свойство. А при каждом таком проходе можно и проверять тот факт, что нужно завершать процесс, а не ждать новых данных.
Available - количество данных в уже подключенном потоке, Accept - прием нового клиента в подключение. Какое отношение одного к другому?

Добавлено через 2 минуты
Цитата Сообщение от Martovskij Посмотреть сообщение
А почему, если не секрет не юзаете socket.BeginAccept()?
Лично у меня, кажется, был и так отдельный поток для этого. Да и проблемы это, наверное, не решает. Всё равно же его не отменить.
0
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 13
27.02.2014, 07:01 13
А этот вопрос решил только через
C#
1
2
socket.BeginAccept(new AsyncCallback(acceptCallBack), this);
            waitAccept.WaitOne();
1
155 / 155 / 30
Регистрация: 19.10.2009
Сообщений: 319
27.02.2014, 14:29 14
Может я перепутал свойство, но последний раз я эту вещь делал именно так - прежде, чем делать Accept, проверял, есть ли данные. Если есть, то он его быстро пройдёт, если нет - так незачем делать Accept раньше, чем появятся данные. В общем, рекомендую этот вариант. А если делать thread.Abort(), то при неблагоприятном стечении обстоятельств (милисекундой раньше - милисекундой позже, тут как повезёт) могут остаться занятые порты до перезагрузки Windows.
0
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
27.02.2014, 20:22  [ТС] 15
Цитата Сообщение от Ilya81 Посмотреть сообщение
прежде, чем делать Accept, проверял, есть ли данные
Если клиент попытается приконнектиться, но на сервере не будет ожидать Accept, первый просто получит отказ на подключение, т.к. порт не прослушиватся. Не могу понять, какие данные можно проверить?
Может быть, Вы путаете Socket.Accept() с Socket.Receive()?
0
3 / 3 / 0
Регистрация: 08.04.2020
Сообщений: 6
27.08.2021, 21:59 16
Понимаю, что некрофилизм, но может пригодиться!

Добавлено через 8 минут
C#
1
2
3
4
5
6
7
8
9
10
11
12
Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
ipPoint = new IPEndPoint(IPAddress.Parse(IpAddr), Port);
socket.Bind(ipPoint);
socket.Listen(Count);
 
while(true)
{
      if (socket.Poll(100,SelectMode.SelectRead))
      {
           Socket newSocket=socket.Accept();
      }
}
Добавлено через 1 минуту
Таким способом блокировки не происходит и цикл постоянно выполняется!
2
Эксперт .NET
1696 / 1325 / 316
Регистрация: 15.06.2012
Сообщений: 5,045
Записей в блоге: 3
28.08.2021, 21:51 17

Не по теме:

Цитата Сообщение от zFire1982 Посмотреть сообщение
Понимаю, что некрофилизм, но может пригодиться!
ничего, сейчас за это накажем! XD


1. тема про завершение операции Accept без исключения, а не проблему блокировок
2. ваш код все также блокирующий и нужно выносить в отдельный поток
3. современный подход подразумевает async-await с отменой задачи. Хотя там ровно также сыпет исключение.
0
3 / 3 / 0
Регистрация: 08.04.2020
Сообщений: 6
06.09.2021, 15:20 18
Wolfdp,
1) Accept в данном случае блокирующая функция, которая отработает только при попытке соединения. При попытке закрыть вызовет ошибку. Так было и в самой библиотеке Winsock. При правильной логике вызов Accept происходит только в момент когда нужно. И проблема исчезает сама собой.

2) Простите, я не представляю как использовать серверный сокет с блокирующими функциями, не используя для него отдельного потока. И каким образом вы подразумеваете закрытие сокета если не использовать закрытие из другого потока?

3) Она и должна сыпать исключениями, т.к. при определенных условиях закрывая гнездо вы нарушаете логику работы. О чем система Вам сообщает.
0
Эксперт .NET
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
06.09.2021, 17:10 19
Цитата Сообщение от zFire1982 Посмотреть сообщение
При правильной логике вызов Accept происходит только в момент когда нужно.
Как определяется момент, что уже нужно вызывать?

Добавлено через 7 минут
Ага, понял, вопрос снимается.
Интересный вариант!
0
Эксперт .NET
1696 / 1325 / 316
Регистрация: 15.06.2012
Сообщений: 5,045
Записей в блоге: 3
07.09.2021, 00:04 20
Цитата Сообщение от zFire1982 Посмотреть сообщение
При правильной логике вызов Accept происходит только в момент когда нужно.
А вот у меня вопрос остался. При таком подходе получаем либо System.ObjectDisposedException: Cannot access a disposed object. (который валит более стабильно), либо System.Net.Sockets.SocketException (10004): A blocking operation was interrupted by a call to WSACancelBlockingCall. (что даже немного озадачивает).
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
        static void Main(string[] args)
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.3"), 12345);
            socket.Bind(ipPoint);
            socket.Listen(10);
 
            Task.Run(()=> 
            {
                try
                {
                    while (true)
                    {
                        if (socket.Poll(100, SelectMode.SelectRead))
                            _ = socket.Accept();
                    }
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex);
                }
            });
 
            Thread.Sleep(10000);
            socket.Close();
            Console.WriteLine("closed");
            
            Console.ReadKey();
        }
Окей, если использовать не чистый сокет
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
            var ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.3"), 12345);
            var l = new TcpListener(ipPoint);
            l.Start();
            var f = true;
 
            Task.Run(()=> 
            {
                try
                {
                    while (f)
                    {
                        if (l.Server.Poll(100, SelectMode.SelectRead))
                            _ = l.Server.Accept();
                    }
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex);
                }
                Console.WriteLine("stoped");
            });
 
            Thread.Sleep(10000);
            f = false;
            l.Stop();
            Console.WriteLine("closed");
            Console.ReadKey();
Либо закрывает без ошибок, либо таки валит SocketException (10004)

Окей, в процессе набора лапками вышеуказаного кода понял что можно сделать следующий финт ушами: устанавливаем флаг отмены, сначала глушим слушающий поток и только потом останавливаем саму прослушку.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
        static void Main(string[] args)
        {
            var ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.3"), 12345);
            var l = new TcpListener(ipPoint);
            l.Start();
            var f = true;
            var stopedListening = new ManualResetEvent(false);
 
            Task.Run(async ()=> 
            {
                try
                {
                    while (f)
                    {
                        if (l.Server.Poll(100, SelectMode.SelectRead))
                            _ = await l.AcceptTcpClientAsync();
                    }
                    stopedListening.Set();
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex);
                }
                Console.WriteLine("stoped");
            });
 
            Thread.Sleep(10000);
            f = false;
            stopedListening.WaitOne();
            l.Stop();
            Console.WriteLine("closed");
            Console.ReadKey();
        }
p.s. у меня есть определенные сомнения насчет перфоменса, когда на сокет ломанется 100500 новых подключений. Мы вместо одного вызова Accept теперь делаем предварительный Poll. Насколько помню, сервер очень не шустро генерит новые подключения.
0
07.09.2021, 00:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.09.2021, 00:04
Помогаю со студенческими работами здесь

Виснет socket.accept()
Ситуация такая. Есть небольшой веб сервер, который в несколько потоков слушает соединения на...

Многопоточный socket accept
Идея запускать сервер на пару минут и потом останавливать. Принятие клиентов разделил на потоки,...

Невозможно создать Socket: Socket sock = new Socket(someHostString,somePortInt);
Народ! Помогите пожалуйста. Вся красота губится на exception что выскакивает в момент создания...

Как прекратить событие
Смысл в том, что при выполнении условия в 78 строке мне нужно чтобы событие FormKeyPress...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru