Форум программистов, компьютерный форум, киберфорум
C#: Веб-сервисы и WCF
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
5 / 5 / 4
Регистрация: 20.01.2011
Сообщений: 350
1
.NET 4.x

TcpSocket: Обычно разрешается только одно использование адреса сокета

26.12.2018, 22:36. Показов 1854. Ответов 2

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

Итак, делаю сервер, который слушает локалку по указанному порту. За основу взял эту библиотеку - https://github.com/nterry/AwesomeSockets. Вот так выглядит метод запуска прослушивания:
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
34
public async void StartListening(int port)
{
    if (CancellationTokenSource == null)
        CancellationTokenSource = new CancellationTokenSource();
    _cancellationToken = CancellationTokenSource.Token;
    Clients = new ObservableCollection<Client>();
    BindingOperations.EnableCollectionSynchronization(Clients, _lockObject);
 
    try
    {
        while (_tcpListen == null)
        {
            ShowCallbackMessageAction?.Invoke("Try to start server");
            _tcpListen = AweSock.TcpListen(port);
 
            if (_tcpListen != null)
            {
                ShowCallbackMessageAction?.Invoke("Server started");
 
                var waitForConnectionTask = Task.Run(() => WaitForConnectionLoop(), _cancellationToken);
                var checkClientsConnectionTask = Task.Run(() => CheckClientsConnectionLoop(), _cancellationToken);
 
                await Task.WhenAll(waitForConnectionTask, checkClientsConnectionTask);
            }
 
            // https://stackoverflow.com/a/32768637/4944499
            await Task.Delay(1000, _cancellationToken).ContinueWith(task => { });
        }
    }
    catch (Exception exception)
    {
        ShowCallbackMessageAction?.Invoke($"Error on start server: {exception.Message}");
    }
}
Вот так метод остановки прослушивания:
C#
1
2
3
4
5
6
7
8
9
10
public void StopListening()
{
    ShowCallbackMessageAction?.Invoke("Begin stop server...");
    ShowCallbackMessageAction?.Invoke("Disconnect all clients");
    DisconnectAllClients();
    CancellationTokenSource?.Cancel();
    _tcpListen?.Close();
    _tcpListen = null;
    ShowCallbackMessageAction?.Invoke("Server stopped");
}
Метод из библиотеки, вызываемый в моем методе StartListening:
C#
1
2
3
4
5
6
7
8
9
10
public static ISocket TcpListen(int port, int backlog = 10)
{
    var listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    //var ip = new IPAddress(new byte[] { 0, 0, 0, 0 });
    //var localEndPoint = new IPEndPoint(ip, port);
    IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);
    listenSocket.Bind(localEndPoint);
    listenSocket.Listen(backlog);
    return AwesomeSocket.New(listenSocket);
}
Так вот - это все работает до того момента, пока я приложение свое не закрою без отписки от прослушивания. Т.е., например, случился крэш. После того, как я повторно запускаю сервер, то вижу сообщение:
TcpSocket: Обычно разрешается только одно использование адреса сокета

Везде пишут, что это нормально и порт сам освободится через некоторое время (вроде 240 секунд), но в моем случае этого не происходит. Помогает только перезагрузка компа. Как быть?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.12.2018, 22:36
Ответы с готовыми решениями:

Обычно разрешается только одно использование адреса сокета (протокол/сетевой адрес/порт)
При запуске вызывается ошибка на строчке с Bind. Обычно разрешается только одно использование...

Error: Обычно разрешается только одно использование адреса сокета (протокол/сетевой адрес/порт)
Можно ли как-то обойти эту ошибку, и отправить пакет на &quot;занятый&quot; адрес/порт

Сокеты. Ошибка «Обычно разрешается одно использование адреса сокета»
Имеется отправка строк string AcceptLogin = Логин.Text + Пароль.Text; //AcceptLogin =...

В сервере ошибка Обычно разрешается одно использование адреса сокета
В сервере моего приложения при отправке файла возникает ошибка &quot;Обычно разрешается одно...

2
Эксперт .NETАвтор FAQ
10410 / 5140 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
27.12.2018, 11:48 2
Modis,
Ну во-первых, с такими вопросами нужно обращаться к разработчику библиотеки. Вы же сами даете ссылку на github. Там есть раздел Issues для таких вещей.

Далее, по сути проблемы. Я немного посмотрел код и думаю, что причина вот в чем. Посмотрите например на вот эту строку:
https://github.com/nterry/Awes... ock.cs#L48
Здесь создается поток Thread. Но дело в том, что по умолчанию, поток - работает в режиме foreground. А это значит что поток не завершается, даже если вы завершаете приложение. Поэтому поток нужно перевести в режим background и тогда он будет автоматически завершаться с завершением приложения:

C#
1
2
var thread = new Thread(() => TcpAcceptThread(listenSocket, callback)) {IsBackground = true};
thread.Start();
Аналогично нужно сделать в других местах, где создаются потоки. Также можно использовать ThreadPool вместо непосредственного создания потоков. Это даже лучше.

Может проблема и не только в этом, это просто бросается в глаза.
1
5 / 5 / 4
Регистрация: 20.01.2011
Сообщений: 350
27.12.2018, 17:27  [ТС] 3
Storm23, спасибо. Отличное замечание

Добавлено через 23 минуты
Цитата Сообщение от Storm23 Посмотреть сообщение
Аналогично нужно сделать в других местах, где создаются потоки. Также можно использовать ThreadPool вместо непосредственного создания потоков
а по хорошему, наверное, заменит все на Task'и нужно

Добавлено через 5 часов 13 минут
Вопрос решен. Проблема в самом неожиданном месте и, надеюсь, кому-то пригодится. Итак, используя командную строку и команду
netstat -a -b
Я выяснил, что порт занимается процессом XDesProc.exe. Погуглив, оказалось, что во всем виноват WPF designer Visual Studio, который пытается имитировать работу окна и тем самым начинает прослушку порта. Просто закрываю редактор xaml и все хорошо становится
0
27.12.2018, 17:27
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.12.2018, 17:27
Помогаю со студенческими работами здесь

Ошибка в клиенте: Обычно разрешается одно использование адреса сокета
Здравствуйте, я изучаю сетевое программирование. Начал программирование сокетов. Вот сервер:...

Обычно разрешается одно использование адреса сокета (протокол/сетевой адрес/порт)
Написал клиент-сервер для передачи файлов(первый опыт). При подключении клиента к серверу дает...

Проблема с UdpClient (разрешается только одно использование адреса сокета)
Есть приложение, которое отсылает содержимое файла на указанный порт: using (UdpClient server =...

Обычно разрешается только одно использование адреса сокета(протокол/сетевой адрес/порт)
Вот возникла проблема, существует многопоточный C# сервер работающий на UDP, слушающий 4 порта и...


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

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