2016-11-04 3 views
0

В WCF службы я заполнить поток согласно this question как:Множественный поток в одном потоке не будет передан клиенту правильно

result.Stream = new MemoryStream(); 
      BinaryWriter writer = new BinaryWriter(result.Stream); 
      foreach (string fileN in zipFiles) 
      { 
       byte[] fileBytes = File.ReadAllBytes(fileN); 
       writer.Write(BitConverter.GetBytes(fileBytes.Length), 0, 4); 
       writer.Write(fileBytes, 0, fileBytes.Length); 
      } 
      writer.Flush(); 
      return result; 

до этого я возвращался поток, это и все работает в сфере услуг и на стороне клиента:

result.Stream = new MemoryStream(File.ReadAllBytes(fileN)); 

поток будет MessageBodyMember но гайка Теперь изменили его, чтобы сохранить все файлы в одном потоке. Метод

и тест на стороне клиента:

ExportClient export = new ExportClient("exportEndPoint"); 
     ExportResult_C result = export.Export(source); 
     result.Stream.Position = 0; 
     //result.Stream.SaveToFile("d:\\kkk.log"); 
     BinaryReader reader = new BinaryReader(result.Stream, System.Text.Encoding.UTF8); 
     string pathToSave = string.Empty; 
     while (result.Stream.Position < result.Stream.Length) 
     { 
      int size = reader.ReadInt32(); 
      byte[] data = reader.ReadBytes(size); 
      pathToSave = "D:\\test\\" + new Random().Next(0, 2564586).ToString() + ".zip"; 
      File.WriteAllBytes(pathToSave, data); 
     } 

конечная точка адрес:

<endpoint address="net.tcp://localhost:2082/Exchange/Export.svc" binding="netTcpBinding" bindingConfiguration="largeSizeStreamTcp" 
    contract="xxx" name="exportEndPoint"/> 

и связывание конфигурации:

<netTcpBinding> 
    <binding openTimeout="00:00:03" maxReceivedMessageSize="2000000000" transferMode="Streamed" maxBufferSize="2000000000" > 
     <readerQuotas maxDepth="32" maxArrayLength="2000000000" maxStringContentLength="2000000000" /> 
     <security mode="None" /> 
    </binding> 
    <binding name="largeSizeStreamTcp" transferMode="Streamed" receiveTimeout="00:30:00" sendTimeout="00:30:00" openTimeout="00:00:01" maxReceivedMessageSize="2000000000" maxBufferSize="2000000000" > 
     <readerQuotas maxDepth="32" maxArrayLength="2000000000" maxStringContentLength="2000000000" /> 
     <security mode="None" /> 
    </binding> 
    </netTcpBinding> 
    <netNamedPipeBinding> 

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

это действительно подталкивает меня к стене !!!

Кто-нибудь знает, почему это произошло (на стороне клиента)?

+0

Я думаю, что привязка плохо или служба связана со связыванием.Убедитесь, что служба получает поток. Клиент отправляет или принимает данные? Похоже, что проводка кода получает поток. Сервер отправляет поток? Я не вижу номеров портов, поэтому порт может быть заблокирован. Используйте номер порта> 10 000, чтобы он не конфликтует с другим приложением и не блокируется. Порты менее 1024 могут блокироваться. – jdweng

+0

Нет, как я уже сказал, я возвращал файловый пар, например, новый MemoryStream (File.ReadAllBytes (fileN)), однако теперь он может возвращать поток до кода снова, он возвращается на клиентскую сторону и сохраняет его обратно (много времени проверяется), номер порта и адрес конечной точки правильно настроены. – Aria

+0

Если TCP настроен правильно, вы можете отправлять данные без привязок? Это проблема только с привязками? Можете ли вы ping LocalHost в cmd.exe? Не все компьютеры настроены на LocalHost. На одном ПК клиент и сервер не могут одновременно использовать localhost. Обычно сервер использует IP.Any. – jdweng

ответ

0

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

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

Итак, на первый шаг Я создал сериализуемый DataContract для хранения имени файла и его содержимого.

[DataContract] 
[Serializable] 
public class ExportSourceFiles_C 
{ 
    [DataMember] 
    public string Name; 
    [DataMember] 
    public byte[] Content; 
} 

на втором этапе список ExportSourceFile_C будет создан, как:

List<ExportSourceFiles_C> sourceFiles = new List<ExportSourceFiles_C>(); 
string[] zipFiles = Directory.GetFiles(zipRoot); 
foreach (string path in zipFiles) 
    { 
    byte[] fileBytes = File.ReadAllBytes(path); 
    sourceFiles.Add(new ExportSourceFiles_C() 
    { 
     Name = Path.GetFileName(path), 
     Content = fileBytes 
    }); 
    } 

на третьем этапе упомянутый список должен быть сериализации в result.Stream как:

result.Stream = new MemoryStream(); 
    BinaryFormatter formatter = new BinaryFormatter(); 
    formatter.Serialize(result.Stream, sourceFiles); 
    result.Stream.Position = 0; 
    return result; 

на стороне клиента достаточно десериализовать поток в список ExportSourceFiles_C так что последний шаг в сторону клиента должно быть что-то вроде этого:

ExportClient export = new ExportClient("exportEndPoint"); 
ExportResult_C result = export.Export(source); 
BinaryFormatter formatter = new BinaryFormatter(); 
List<ExportSourceFiles_C> deserialisedFiles = (List<ExportSourceFiles_C>)formatter.Deserialize(result.Stream); 
foreach (ExportSourceFiles_C file in deserialisedFiles) 
     File.WriteAllBytes("d:\\" + file.Name, file.Content); 

все работает как шарм без каких-либо проблем.

наслаждаться.