Может кто-нибудь объяснить, как эта серверная программа закрывает свой сокет после каждого соединения?И как я могу держать розетку открытой? - PullRequest
0 голосов
/ 11 апреля 2019

Итак, я хочу установить TCP-соединение между двумя приложениями UWP, используя потоковые сокеты. Я нашел этот пример на веб-странице Microsoft, и он работает. Проблема в том, что он закрывает свои сокеты после каждого соединения, которое было установлено. Я хочу понять, когда он закрывается (не могу найти его в коде, и это немного смущает меня), и я также хочу знать, как я могу сохранить соединение между сервером и клиентом открытым, чтобы мне не приходилось каждый раз переподключаться Я хочу что-то отправить.

Пример: https://docs.microsoft.com/en-us/windows/uwp/networking/sockets#build-a-basic-tcp-socket-client-and-server

Я посмотрел документацию по StreamSocket для Windows и не могу найти что-то о закрытии сокета.

Я предполагаю, что это происходит где-то в этом методе. Это серверная часть программы, которая выполняется при получении соединения.

private async void StreamSocketListener_ConnectionReceived
(Windows.Networking.Sockets.StreamSocketListener sender,   
Windows.Networking.Sockets.
StreamSocketListenerConnectionReceivedEventArgs args)
{
    string request;
    using (var streamReader = new   
    StreamReader(args.Socket.InputStream.AsStreamForRead()))
    {
        request = await streamReader.ReadLineAsync();
    }

    await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>    this.serverListBox.Items.Add(string.Format("server received the request: \"{0}\"", request)));

// Echo the request back as the response.
using (Stream outputStream = args.Socket.OutputStream.AsStreamForWrite())
{
    using (var streamWriter = new StreamWriter(outputStream))
    {
        await streamWriter.WriteLineAsync(request);
        await streamWriter.FlushAsync();
    }
}

string request;
using (var streamReader = new
StreamReader(args.Socket.InputStream.AsStreamForRead()))
{
    request = await streamReader.ReadLineAsync();
}

await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
this.serverListBox.Items.Add(string.Format("server received the 
request: \"{0}\"", request)));

// Echo the request back as the response.
using (Stream outputStream =   
args.Socket.OutputStream.AsStreamForWrite())
{
    using (var streamWriter = new StreamWriter(outputStream))
    {
        await streamWriter.WriteLineAsync(request);
        await streamWriter.FlushAsync();
    }
}

await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => 
this.serverListBox.Items.Add(string.Format("server sent back the 
response: \"{0}\"", request)));

sender.Dispose();

await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => 
this.serverListBox.Items.Add("server closed its socket"));

}

Любая помощь будет принята с благодарностью!

1 Ответ

1 голос
/ 11 апреля 2019

Я нашел этот пример на веб-странице Microsoft, и он работает.

К сожалению, все примеры сокетов Microsoft не хорошие примеры написания приложений сокетов,Это только примеров того, как вызывать эти API.Создание приложения сокетов производственного качества не является тривиальным, и примеры сокетов Microsoft могут ввести вас в заблуждение.

Например, этот сервер сокетов:

  • использует Dispatcher для обновленияПользовательский интерфейс, а не современные решения, такие как IProgress<T>.
  • Читает из входного потока, пока не будет найдена новая строка.Это проблема, потому что:
    • Время ожидания для запроса не истекло.
    • Входной буфер увеличивается без границ.
    • Нет обработки полуоткрытого сценария.

Большинство примеров сокетов от Microsoft имеют те же проблемы, которые необходимо решать при написании кода сокетов производственного качества.И писать код сокетов производственного качества гораздо сложнее, чем кажется на первый взгляд.

По этой причине я всегда рекомендую использовать альтернативную технологию (например, самодостаточный SignalR), если это возможно.

Ночтобы ответить на ваш актуальный вопрос:

Я хочу понять, когда он закрывается

С сокетами на самом деле есть два потока: входной поток ивыходной поток.Оба закрываются, когда вызывается sender.Dispose();.Тем не менее, входной поток также закрыт, когда расположен StreamReader, а выходной поток также закрыт, когда расположен StreamWriter.Это происходит в конце их using блоков.Вот почему вы не можете прочитать второе сообщение после закрытия StreamReader.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...