У меня есть написанное мной фоновое приложение UWP, которое работает на Raspberry Pi с последней версией Windows IoT. Его цель - обрабатывать http-запросы и возвращать ответы нескольким мобильным приложениям.
Он отлично работает, за исключением того, что порт прослушивания на сокете иногда зависает. Остальная часть фонового приложения остается отзывчивой, поэтому я знаю, что приложение все еще работает. Но запросы http перестают отвечать. Обычно для решения проблемы достаточно войти в панель IoT и перезапустить мое приложение. Но я не могу понять, почему приложение иногда зависает.
Вот фрагмент кода, который, я думаю, имеет отношение:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using Windows.ApplicationModel.Background;
using Windows.Networking.Sockets;
namespace MyApp.Sandbox
{
public class SystemTest : IBackgroundTask
{
private StreamSocketListener listener = null;
public void Run(IBackgroundTaskInstance taskInstance)
{
StartServer();
}
public async void StartServer()
{
try
{
int port = 8189;
listener = new StreamSocketListener();
var currentSetting = listener.Control.QualityOfService;
listener.Control.QualityOfService = SocketQualityOfService.LowLatency;
await listener.BindServiceNameAsync(port.ToString());
listener.ConnectionReceived += async (sender, args) =>
{
var request = new StringBuilder();
using (var input = args.Socket.InputStream.AsStreamForRead())
{
int maxBuffer = 8192;
int index = 0;
List<byte> line = new List<byte>();
int b;
while (true)
{
try
{
b = input.ReadByte();
line.Add((byte)b);
if (b == 10 && line.Count >= 2)
{
if (line[line.Count - 2] == 13 && line[line.Count - 1] == 10)
{
byte[] byteArray = line.ToArray();
var dataString = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
request.Append(dataString);
line = new List<byte>();
if (request.ToString().StartsWith("GET"))
{
break;
}
if (request.ToString().StartsWith("POST") &&
request.ToString().Contains(Environment.NewLine + Environment.NewLine))
{
string contentLength = GetValueFromHeader("Content-Length", request.ToString());
if (!contentLength.Equals(""))
{
int length = Convert.ToInt32(contentLength);
if (length > 0)
{
byteArray = new byte[length];
input.Read(byteArray, 0, length);
dataString = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
request.Append(dataString);
}
}
break;
}
}
}
index++;
if (index > maxBuffer)
{
break;
}
}
catch
{
break;
}
}
input.Dispose();
}
using (var output = args.Socket.OutputStream)
{
using (var response = output.AsStreamForWrite())
{
var requestLines = request.ToString().Split(' ');
var url = requestLines.Length > 1 ? requestLines[1] : string.Empty;
string postLine = null;
if (requestLines.Length > 0)
{
if (requestLines[0] == "POST")
{
postLine = requestLines[requestLines.Length - 1];
}
}
string str = null;
try
{
// handle response here which fills "str"
}
catch (Exception innerEx)
{
Debug.WriteLine(innerEx.Message);
Debug.WriteLine(innerEx.StackTrace);
}
var html = Encoding.UTF8.GetBytes(str);
using (var bodyStream = new MemoryStream(html))
{
var header = $"HTTP/1.1 200 OK\r\nContent-Length: {bodyStream.Length}\r\nContent-Type: application/json\r\ncharset: UTF-8\r\nConnection: close\r\n\r\n";
var headerArray = Encoding.UTF8.GetBytes(header);
await response.WriteAsync(headerArray, 0, headerArray.Length);
await bodyStream.CopyToAsync(response);
await response.FlushAsync();
}
}
output.Dispose();
}
};
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
}
}
}
}
Я подтвердил, что «Компилировать с. NET Native Toolchain "включен в моей конфигурации сборки. И я запускаю это в режиме выпуска.
Я не уверен, что мне нужно сделать что-то другое, чтобы освободить входящие соединения? Возможно, он зависает, потому что поступает несколько запросов одновременно, и он не может его обработать?
Вот пример того, как выглядит netstat, когда порт (в данном случае это 8081) зависает:
TCP 192.168.1.190:8081 5.101.0.209:32880 CLOSE_WAIT
TCP 192.168.1.190:8081 5.101.0.209:33494 CLOSE_WAIT
TCP 192.168.1.190:8081 5.101.0.209:60412 CLOSE_WAIT
TCP 192.168.1.190:8081 Mike-PC:59879 CLOSE_WAIT
TCP 192.168.1.190:8081 Mike-PC:59880 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:43096 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:43110 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:43114 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:43120 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:43130 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:43742 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:43744 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:43750 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:43822 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:43914 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:43986 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:48646 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:48648 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:48702 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:48724 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:48774 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:48776 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:48820 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:48834 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:48918 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:49036 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:49058 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:49284 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:49416 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:49672 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:49680 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:50360 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:50566 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:50718 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:50724 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:50734 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:50938 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:51082 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:51524 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:51880 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:51946 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:52146 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:52212 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:52224 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:52310 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:53126 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:53206 CLOSE_WAIT
TCP 192.168.1.190:8081 Galaxy-S20-5G:53284 CLOSE_WAIT
TCP 192.168.1.190:8081 192.227.118.82:1550 ESTABLISHED
TCP 192.168.1.190:59613 52.242.211.89:https ESTABLISHED
TCP [::]:22 myapp:0 LISTENING
TCP [::]:135 myapp:0 LISTENING
TCP [::]:445 myapp:0 LISTENING
TCP [::]:5985 myapp:0 LISTENING
TCP [::]:8080 myapp:0 LISTENING
TCP [::]:8081 myapp:0 LISTENING
TCP [::]:47001 myapp:0 LISTENING
TCP [::]:49664 myapp:0 LISTENING
TCP [::]:49665 myapp:0 LISTENING
TCP [::]:49667 myapp:0 LISTENING
UDP 0.0.0.0:123 *:*
UDP 0.0.0.0:5050 *:*
UDP 0.0.0.0:5353 *:*
UDP 0.0.0.0:5355 *:*
UDP 0.0.0.0:29819 *:*
UDP 0.0.0.0:51049 *:*
UDP [::]:123 *:*
UDP [::]:5353 *:*
UDP [::]:5355 *:*
На данный момент я открыт для предложений, если кто-то еще столкнулся с подобной ситуацией ....
Спасибо!