Я разрабатываю простое приложение для отправки файлов по TCP с использованием классов TCPListener и TCPClient. Вот код, который отправляет файл.
Stop - это логическое значение volatile, которое помогает остановить процесс в любое время, а WRITE_BUFFER_SIZE может быть изменено во время выполнения (другое значение volatile)
while (remaining > 0 && !stop)
{
DateTime current = DateTime.Now;
int bufferSize = WRITTE_BUFFER_SIZE;
buffer = new byte[bufferSize];
int readed = fileStream.Read(buffer, 0, bufferSize);
stream.Write(buffer, 0, readed);
stream.Flush();
remaining -= readed;
// Wait in order to guarantee send speed
TimeSpan difference = DateTime.Now.Subtract(current);
double seconds = (bufferSize / Speed);
int wait = (int)Math.Floor(seconds * 1000);
wait -= difference.Milliseconds;
if (wait > 10)
Thread.Sleep(wait);
}
stream.Close();
и это код, который обрабатывает сторону получателя:
do
{
readed = stream.Read(buffer, 0, READ_BUFFER_SIZE);
// write to .part file and flush to disk
outputStream.Write(buffer, 0, readed);
outputStream.Flush();
offset += readed;
} while (!stop && readed > 0);
Теперь, когда скорость низкая (около 5 Кбит / с), все работает нормально, но, по мере увеличения скорости, размер приемника становится более склонным к возникновению исключения SocketException при чтении из потока. Я предполагаю, что это связано с закрытием удаленного сокета до того, как все данные будут прочитаны, но как правильно это сделать? Когда мне следует закрыть отправляющего клиента?
Я не нашел хороших примеров передачи файлов в Google, и те, которые я нашел, имеют аналогичную реализацию того, что я делаю, поэтому я предполагаю, что что-то упустил.
Редактировать: Я получаю эту ошибку "Невозможно прочитать данные из транспортного соединения". Это IOException, внутренним исключением которого является SocketException.
Я добавил это в функцию отправителя, но все равно получаю ту же ошибку, код никогда не достигает stream.close () и, конечно, tcpclient никогда не закрывается ... так что я полностью потерян.
buffer = new byte[1];
client.Client.Receive(buffer);
stream.Close();