有人可以解释一下该服务器程序在每次连接后如何关闭其套接字吗?我如何保持插座打开?

时间:2019-04-11 11:33:58

标签: c# sockets tcp uwp

所以我想使用流束在2个UWP应用之间建立TCP连接。我在Microsoft网页上找到了此示例,并且可以正常工作。问题是在建立每个连接后,它都会关闭套接字。我想了解它何时关闭(在代码中找不到它,这让我有些困惑),而且我还想知道如何保持服务器和客户端之间的连接打开,因此不必每次都重新连接我想发送一些东西。

示例:https://docs.microsoft.com/en-us/windows/uwp/networking/sockets#build-a-basic-tcp-socket-client-and-server

我看过Windows上的StreamSocket文档,却找不到与关闭套接字有关的东西。

我认为它发生在此方法的某处。收到连接后,将执行程序的服务器端。

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 个答案:

答案 0 :(得分:1)

  

我在Microsoft网页上找到了这个示例,并且可以正常工作。

不幸的是,所有Microsoft套接字示例都不是关于如何编写套接字应用程序的好示例。它们仅是有关如何调用这些API的示例。构建具有生产质量的套接字应用程序并非易事,Microsoft套接字示例将误导您。

例如,此套接字服务器:

  • 使用Dispatcher来更新UI,而不是使用IProgress<T>之类的现代解决方案。
  • 从其输入流读取,直到找到换行符。这是一个问题,因为:
    • 请求没有超时。
    • 输入缓冲区无限制地增长。
    • 半开放方案没有处理。

Microsoft的大多数套接字示例都具有相同的问题,编写生产质量的套接字代码时必须解决所有这些问题。而且编写具有生产质量的套接字代码比最初看起来要困难得多。

因此,我总是建议尽可能使用其他技术(例如,自托管的SignalR)。

但是要回答您的实际问题:

  

我想了解它何时关闭

在使用套接字的情况下,实际上有两个 流:一个输入流和一个输出流。调用sender.Dispose();时,两者都关闭。但是,当放置StreamReader时,输入流也 关闭,而当放置StreamWriter时,输出流也 关闭。这些发生在它们的using块的末尾。这就是为什么在关闭StreamReader之后无法阅读第二条消息的原因。