Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在UWP中使用StreamSocket时,如何知道套接字连接是否仍然有效?_C#_Sockets_Win Universal App - Fatal编程技术网

C# 在UWP中使用StreamSocket时,如何知道套接字连接是否仍然有效?

C# 在UWP中使用StreamSocket时,如何知道套接字连接是否仍然有效?,c#,sockets,win-universal-app,C#,Sockets,Win Universal App,我使用StreamSocket连接到套接字服务器,并使用无限循环读取数据。每段数据都以'\n\n'结尾。代码片段如下所示。但是,我不知道套接字是否仍处于活动状态,每次服务器关闭连接时,ReadAsync()都会抛出异常。如何在连接关闭时收到通知 public async Task<string> ReadData() { StreamReader reader = new StreamReader(socket.InputStream.AsStreamForRead());

我使用
StreamSocket
连接到套接字服务器,并使用无限循环读取数据。每段数据都以
'\n\n'
结尾。代码片段如下所示。但是,我不知道套接字是否仍处于活动状态,每次服务器关闭连接时,
ReadAsync()
都会抛出异常。如何在连接关闭时收到通知

public async Task<string> ReadData() {
    StreamReader reader = new StreamReader(socket.InputStream.AsStreamForRead());
    char[] ch = new char[65536];
    int i = 0;
    while (IsConnected) {
        await reader.ReadAsync(ch, i++, 1);
        if (i > 1 && ch[i - 1] == '\n' && ch[i - 2] == '\n') break;
    }
    return new StringBuilder().Append(ch, 0, i - 2).ToString();
}
public异步任务ReadData(){
StreamReader=新的StreamReader(socket.InputStream.AsStreamForRead());
char[]ch=新字符[65536];
int i=0;
while(断开连接){
wait reader.ReadAsync(ch,i++,1);
如果(i>1&&ch[i-1]='\n'&&ch[i-2]='\n')中断;
}
返回新的StringBuilder();
}
每次服务器关闭连接时,ReadAsync()都会抛出异常

引发异常的原因是发生了不正常的断开连接。因此,在关闭服务器端的连接之前,请确保套接字上不存在任何挂起的读取或写入操作,这样就不会有异常。有关详细信息,请参阅的备注部分

如何在连接关闭时收到通知

public async Task<string> ReadData() {
    StreamReader reader = new StreamReader(socket.InputStream.AsStreamForRead());
    char[] ch = new char[65536];
    int i = 0;
    while (IsConnected) {
        await reader.ReadAsync(ch, i++, 1);
        if (i > 1 && ch[i - 1] == '\n' && ch[i - 2] == '\n') break;
    }
    return new StringBuilder().Append(ch, 0, i - 2).ToString();
}
另一侧可以检测到一个优美的套接字闭合,即0长度的读取。也就是说,它的行为就像一个常规的流结束。是一个类似的线程供您参考

因此,您可以使用以下代码检查场景中的连接是否已关闭:

// break when the connection is closed
if (ch[i - 1] == '\0') break;
以下是我验证过的整个方法:

public async Task<string> ReadData()
{
    StreamReader reader = new StreamReader(socket.InputStream.AsStreamForRead());
    char[] ch = new char[65536];
    int i = 0;
    while (true)
    {
        await reader.ReadAsync(ch, i++, 1);
        // break when the connection is closed or data ends with '\n\n'
        if (ch[i - 1] == '\0' || (i > 1 && ch[i - 1] == '\n' && ch[i - 2] == '\n')) break;
    }

    if (ch[i - 1] == '\0')
    {
        // do something here when the connection is closed
    }
    else
    {
        return new StringBuilder().Append(ch, 0, i - 2).ToString();
    }
}
public异步任务ReadData()
{
StreamReader=新的StreamReader(socket.InputStream.AsStreamForRead());
char[]ch=新字符[65536];
int i=0;
while(true)
{
wait reader.ReadAsync(ch,i++,1);
//连接关闭或数据以“\n\n”结尾时中断
如果(ch[i-1]='\0'| |(i>1&&ch[i-1]='\n'&&ch[i-2]='\n'))中断;
}
如果(ch[i-1]='\0')
{
//当连接关闭时,在此处执行某些操作
}
其他的
{
返回新的StringBuilder();
}
}
每次服务器关闭连接时,ReadAsync()都会抛出异常

引发异常的原因是发生了不正常的断开连接。因此,在关闭服务器端的连接之前,请确保套接字上不存在任何挂起的读取或写入操作,这样就不会有异常。有关详细信息,请参阅的备注部分

如何在连接关闭时收到通知

public async Task<string> ReadData() {
    StreamReader reader = new StreamReader(socket.InputStream.AsStreamForRead());
    char[] ch = new char[65536];
    int i = 0;
    while (IsConnected) {
        await reader.ReadAsync(ch, i++, 1);
        if (i > 1 && ch[i - 1] == '\n' && ch[i - 2] == '\n') break;
    }
    return new StringBuilder().Append(ch, 0, i - 2).ToString();
}
另一侧可以检测到一个优美的套接字闭合,即0长度的读取。也就是说,它的行为就像一个常规的流结束。是一个类似的线程供您参考

因此,您可以使用以下代码检查场景中的连接是否已关闭:

// break when the connection is closed
if (ch[i - 1] == '\0') break;
以下是我验证过的整个方法:

public async Task<string> ReadData()
{
    StreamReader reader = new StreamReader(socket.InputStream.AsStreamForRead());
    char[] ch = new char[65536];
    int i = 0;
    while (true)
    {
        await reader.ReadAsync(ch, i++, 1);
        // break when the connection is closed or data ends with '\n\n'
        if (ch[i - 1] == '\0' || (i > 1 && ch[i - 1] == '\n' && ch[i - 2] == '\n')) break;
    }

    if (ch[i - 1] == '\0')
    {
        // do something here when the connection is closed
    }
    else
    {
        return new StringBuilder().Append(ch, 0, i - 2).ToString();
    }
}
public异步任务ReadData()
{
StreamReader=新的StreamReader(socket.InputStream.AsStreamForRead());
char[]ch=新字符[65536];
int i=0;
while(true)
{
wait reader.ReadAsync(ch,i++,1);
//连接关闭或数据以“\n\n”结尾时中断
如果(ch[i-1]='\0'| |(i>1&&ch[i-1]='\n'&&ch[i-2]='\n'))中断;
}
如果(ch[i-1]='\0')
{
//当连接关闭时,在此处执行某些操作
}
其他的
{
返回新的StringBuilder();
}
}
每次服务器关闭连接时,ReadAsync()都会引发异常

大多数服务器都会出现这种情况。TCP/IP有一个相当昂贵的四部分握手来优雅地关闭连接,但从服务器的角度来看,要回收这些资源需要很长时间。因此,许多服务器只是“猛击”连接关闭,导致
SocketError.ConnectionReset
错误

正如我在我的博客文章中所描述的,如果通信状态是这样的,你会考虑到一个“优美的关闭”在那个时候是合适的,那么你也应该接受一个异常,在同一个点上使用<代码>连接重置< /代码>。(在您的情况下,适当的“关闭”点是消息是否以
\n\n
完成)

如何在连接关闭时收到通知

public async Task<string> ReadData() {
    StreamReader reader = new StreamReader(socket.InputStream.AsStreamForRead());
    char[] ch = new char[65536];
    int i = 0;
    while (IsConnected) {
        await reader.ReadAsync(ch, i++, 1);
        if (i > 1 && ch[i - 1] == '\n' && ch[i - 2] == '\n') break;
    }
    return new StringBuilder().Append(ch, 0, i - 2).ToString();
}
您将获得一个
ConnectionReset
异常(如果它突然关闭),或者
ReadAsync
将返回
0
(如果它正常关闭)

然而

如何知道套接字连接是否仍处于活动状态

只有一种可靠的方法可以检测套接字连接是否仍然可行:向其写入数据。我在网上的博客文章中详细介绍了这一点

由于套接字通信中的这一相当有趣的怪癖,像
while(IsConnected)
这样的代码是一种反模式。相反,您需要有一个定期轮询循环,该循环根据计时器将数据发送到另一端

注意:如果可能,使用信号器代替原始插座。他们为你做所有艰难的事情

每次服务器关闭连接时,ReadAsync()都会引发异常

大多数服务器都会出现这种情况。TCP/IP有一个相当昂贵的四部分握手来优雅地关闭连接,但从服务器的角度来看,要回收这些资源需要很长时间。因此,许多服务器只是“猛击”连接关闭,导致
SocketError.ConnectionReset
错误

正如我在我的博客文章中所描述的,如果通信状态是这样的,你会考虑到一个“优美的关闭”在那个时候是合适的,那么你也应该接受一个异常,在同一个点上使用<代码>连接重置< /代码>。(在您的情况下,适当的“关闭”点是