Как дождаться завершения потоковой записи

У меня есть серверное приложение, которое прослушивает соединения через порт 8888. Я также создаю клиентское приложение. Это простое приложение, единственное сложное в нем — управление несколькими соединениями. так что мне просто нужно отправлять файлы между компьютерами, поэтому то, как я это делаю, я не знаю, правильно ли это, но это работает, может быть, вы, ребята, поправите меня. вот мой алгоритм при отправке файла:

NetworkStream stream = \\ initialize it

while(someCondition)
{
  // first I open the file for reading and read chunks of it
  byte[] chunk = fileRead(file, indexStart, indexEnd) // I have a similar method this is just to illustate my point

  stream.Write(chunk, \\other params)

   // since I often send large files it will be nice if I can wait here 
   // until the stream.Write is done. when debuging this the while loop 
   // executes several times then it waits. 

}

а с другой стороны я читаю байты из этого потока и записываю их в файл.

Мне также иногда приходится ждать, потому что я отправляю несколько файлов и хочу убедиться, что первый файл был отправлен, прежде чем переходить к следующему. Я знаю, что могу решить эту проблему, используя метод stream.Read после завершения передачи. и отправка данных обратно от клиента. но иногда я считаю, что будет полезно знать, когда поток.запись завершена.


Редактировать

хорошо, основываясь на ваших ответах, я могу, например, отправить клиенту количество байтов, которое я планирую отправить. и как только клиент получает это количество байтов, это означает, что это сделано. Но мой вопрос в том, эффективно ли это. Я имею в виду делать что-то вроде

на сервере:

запись данных "отправка длины файла"

читать данные «проверить, получил ли клиент длину» (например, ожидая строки в порядке)

записать данные "сообщить клиенту имя файла"

читать данные "проверить, получил ли клиент имя файла"

записать данные "начать отправку фрагментов файла"

читать данные "подождите, пока клиент не ответит, например, строкой ok"


person Tono Nam    schedule 31.08.2011    source источник
comment
Я что-то упускаю? Вызов stream.Write будет блокироваться, поэтому он всегда ожидает завершения. msdn.microsoft.com/en-us/ библиотека/   -  person Tejs    schedule 31.08.2011
comment
Я не думаю, что это так, потому что раньше я сообщал клиенту, что файл был отправлен, вызывая метод. stream.Write( ‹done›.toByteArray,...) и эту строку, которую я отправил, очевидно, когда я закончил отправлять файл правильно. но иногда эта строка была получена раньше, а фрагменты файла позже...   -  person Tono Nam    schedule 31.08.2011
comment
другими словами, клиент приложение, которое получало файл, который я использовал для проверки каждый раз, была ли отправлена ​​строка длины x, и если она была равна ‹done›, чтобы закрыть файл, но иногда ‹done› отправлялся раньше других частей файла, из-за чего файл становится неполным..   -  person Tono Nam    schedule 31.08.2011
comment
Тогда это звучит как неправильная логика приема...   -  person Tejs    schedule 31.08.2011
comment
У меня просто есть цикл, и внутри него у меня есть stream.read(data...) данные при записи в файл записываются по порядку, но строка ‹done› иногда отправляется с другими частями файла при отправке больших файлов . В противном случае клиент всегда будет прослушивать строку ‹done›.   -  person Tono Nam    schedule 31.08.2011
comment
Вам не нужны все проверки чтения данных, чтобы увидеть, получил ли клиент шаги XXX. TCP — это потоковый протокол. Пир будет получать все, что вы отправляете, в том порядке, в котором вы это отправляете. Просто отправьте длину, за которой следуют данные, затем, возможно, больше пар {длина, данные}, а затем закройте сокет.   -  person user207421    schedule 02.09.2011


Ответы (2)


Запись завершена, когда строка

stream.Write(chunk, \\other params)

завершает. Стоит отметить, что это не означает, что другой конец что-то получил. На самом деле, сразу после этой строки данные, вероятно, находятся в каком-то буфере на машине-отправителе. Это означает, что теперь это вне вашего контроля. Если вы хотите получить подтверждение получения, удаленный конец должен сообщить вам об этом.

person spender    schedule 31.08.2011
comment
так что это все объясняет. по этой причине клиент может получить строку ‹done› в сочетании с фрагментами файла, верно? - person Tono Nam; 31.08.2011
comment
покупатель взгляните на мое редактирование. это означает, что мне придется сделать что-то вроде моего редактирования. Это правильный путь? Я считаю, что будет эффективнее просто отправлять данные и намного быстрее. но, как вы упомянули, нет способа убедиться, что кусок был получен клиентом... - person Tono Nam; 31.08.2011

Stream.Write является синхронным, поэтому он всегда будет блокировать ваш поток, пока не завершится запись.

person SergioC    schedule 31.08.2011