У нас есть требование загрузить большие файлы прошивки на принтеры для обновления прошивки устройства. Устройство принтера находится в той же сети, что и мой сервер, и размер прошивки, которую мы пытаемся загрузить, составляет примерно 200 - 500 МБ. Подход, который мы выбрали, заключается в загрузке прошивки (.bin-файла) в поток Памяти и записи ее в куски по сети с использованием TcpClient
.Лучший способ записи больших данных по сетевому потоку TcpClient
Основываясь на ответе сетевого потока, мы показываем статус обновления прошивки для клиента. Ниже приведен фрагмент кода, который мы использовали для обновления прошивки. Я хочу знать, лучший ли это подход, поскольку неправильный может нанести вред устройству.
EDIT:
class MyClass
{
int port = 9100;
string _deviceip;
byte[] m_ReadBuffer = null;
TcpClient _tcpclient;
NetworkStream m_NetworkStream;
static string CRLF = "\r\n";
public event EventHandler<DeviceStatus> onReceiveUpdate;
public async Task<bool> UploadFirmware(Stream _stream)
{
bool success = false;
try
{
_tcpclient = new TcpClient();
_tcpclient.Connect(_deviceip, port);
_stream.Seek(0, SeekOrigin.Begin);
m_NetworkStream = _tcpclient.GetStream();
byte[] buffer = new byte[1024];
m_ReadBuffer = new byte[1024];
int readcount = 0;
m_NetworkStream.BeginRead(m_ReadBuffer, 0, m_ReadBuffer.Length,
new AsyncCallback(EndReceive), null);
await Task.Run(() =>
{
while ((readcount = _stream.Read(buffer, 0, buffer.Length)) > 0)
{
m_NetworkStream.Write(buffer, 0, readcount);
m_NetworkStream.Flush();
}
});
success = true;
}
catch (Exception ex)
{
upgradeStatus = false;
}
return success;
}
private void EndReceive(IAsyncResult ar)
{
try
{
int nBytes;
nBytes = m_NetworkStream.EndRead(ar);
if (nBytes > 0)
{
string res = Encoding.UTF8.GetString(m_ReadBuffer, 0, nBytes);
DeviceStatus status = new DeviceStatus();
string[] readlines = res.Split(new string[] { CRLF },
StringSplitOptions.RemoveEmptyEntries);
foreach (string readline in readlines)
{
if (readline.StartsWith("CODE"))
{
//read readline string here
break;
}
}
}
if (m_NetworkStream.CanRead)
{
do
{
m_NetworkStream.BeginRead(m_ReadBuffer, 0, m_ReadBuffer.Length, new
AsyncCallback(EndReceive), null);
} while (m_NetworkStream.DataAvailable);
}
}
catch (ObjectDisposedException ods)
{
return;
}
catch (System.IO.IOException ex)
{
}
}
}
Любая помощь будет очень ценна.
Я не посылаю его сразу. Возможно, вы не заметили, я отправляю данные в куски во время цикла. – Saket
TCP не предоставляет семантику пакета.Это непрерывный поток байтов, и приложения не могут сделать ничего плохого, отправив определенные пакеты, потому что приложения вообще не отправляют пакеты. – usr