gpt4 book ai didi

c# - 无法将数据写入传输连接 : An existing connection was forcibly closed by the remote host

转载 作者:可可西里 更新时间:2023-11-01 02:31:06 25 4
gpt4 key购买 nike

我有一个更新服务器,它通过 TCP 端口 12000 发送客户端更新。单个文件的发送仅在第一次成功,但之后我在服务器上收到错误消息“无法将数据写入传输连接: 现有连接被远程主机强行关闭”。如果我在服务器上重新启动更新服务,它只会再次运行一次。我有正常的多线程 Windows 服务。

服务器代码

namespace WSTSAU
{
public partial class ApplicationUpdater : ServiceBase
{
private Logger logger = LogManager.GetCurrentClassLogger();
private int _listeningPort;
private int _ApplicationReceivingPort;
private string _setupFilename;
private string _startupPath;
public ApplicationUpdater()
{
InitializeComponent();
}

protected override void OnStart(string[] args)
{
init();
logger.Info("after init");
Thread ListnerThread = new Thread(new ThreadStart(StartListener));
ListnerThread.IsBackground = true;
ListnerThread.Start();
logger.Info("after thread start");
}

private void init()
{
_listeningPort = Convert.ToInt16(ConfigurationSettings.AppSettings["ListeningPort"]);
_setupFilename = ConfigurationSettings.AppSettings["SetupFilename"];
_startupPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Substring(6);
}

private void StartListener()
{
try
{
logger.Info("Listening Started");
ThreadPool.SetMinThreads(50, 50);
TcpListener listener = new TcpListener(_listeningPort);
listener.Start();
while (true)
{
TcpClient c = listener.AcceptTcpClient();
ThreadPool.QueueUserWorkItem(ProcessReceivedMessage, c);
}
}
catch (Exception ex)
{
logger.Error(ex.Message);
}
}

void ProcessReceivedMessage(object c)
{
try
{
TcpClient tcpClient = c as TcpClient;
NetworkStream Networkstream = tcpClient.GetStream();
byte[] _data = new byte[1024];
int _bytesRead = 0;

_bytesRead = Networkstream.Read(_data, 0, _data.Length);

MessageContainer messageContainer = new MessageContainer();
messageContainer = SerializationManager.XmlFormatterByteArrayToObject(_data, messageContainer) as MessageContainer;

switch (messageContainer.messageType)
{
case MessageType.ApplicationUpdateMessage:
ApplicationUpdateMessage appUpdateMessage = new ApplicationUpdateMessage();
appUpdateMessage = SerializationManager.XmlFormatterByteArrayToObject(messageContainer.messageContnet, appUpdateMessage) as ApplicationUpdateMessage;
Func<ApplicationUpdateMessage, bool> HandleUpdateRequestMethod = HandleUpdateRequest;
IAsyncResult cookie = HandleUpdateRequestMethod.BeginInvoke(appUpdateMessage, null, null);
bool WorkerThread = HandleUpdateRequestMethod.EndInvoke(cookie);
break;
}
}
catch (Exception ex)
{
logger.Error(ex.Message);
}
}


private bool HandleUpdateRequest(ApplicationUpdateMessage appUpdateMessage)
{
try
{
TcpClient tcpClient = new TcpClient();
NetworkStream networkStream;
FileStream fileStream = null;

tcpClient.Connect(appUpdateMessage.receiverIpAddress, appUpdateMessage.receiverPortNumber);
networkStream = tcpClient.GetStream();

fileStream = new FileStream(_startupPath + "\\" + _setupFilename, FileMode.Open, FileAccess.Read);

FileInfo fi = new FileInfo(_startupPath + "\\" + _setupFilename);

BinaryReader binFile = new BinaryReader(fileStream);

FileUpdateMessage fileUpdateMessage = new FileUpdateMessage();
fileUpdateMessage.fileName = fi.Name;
fileUpdateMessage.fileSize = fi.Length;

MessageContainer messageContainer = new MessageContainer();
messageContainer.messageType = MessageType.FileProperties;
messageContainer.messageContnet = SerializationManager.XmlFormatterObjectToByteArray(fileUpdateMessage);

byte[] messageByte = SerializationManager.XmlFormatterObjectToByteArray(messageContainer);

networkStream.Write(messageByte, 0, messageByte.Length);

int bytesSize = 0;
byte[] downBuffer = new byte[2048];

while ((bytesSize = fileStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
networkStream.Write(downBuffer, 0, bytesSize);
}

fileStream.Close();
tcpClient.Close();
networkStream.Close();

return true;
}
catch (Exception ex)
{
logger.Info(ex.Message);
return false;
}
finally
{
}
}


protected override void OnStop()
{
}
}

我必须注意我的 Windows 服务(服务器)是多线程的。

最佳答案

在接收端,设置一个 while 循环来监听直到没有更多数据,然后优雅地退出:关闭流和客户端。框架 TCP 库认为在线程退出时放弃冷连接是一个问题,因此会抛出您所看到的异常。

这还将使您免于在更正当前问题后可能会遇到的间歇性问题:使用长度说明符的 Stream.Read 不会每次都为您提供完整的缓冲区。看起来您正在发送(最多)2kb block 并接收到(单发)1kb 缓冲区,所以您也可能开始遇到 XML 异常。

如果这还不够详细,请询问,我会挖掘一些旧的 TcpClient 代码。

关于c# - 无法将数据写入传输连接 : An existing connection was forcibly closed by the remote host,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3645861/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com