Гость
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / Как передать Stream через WCF? (или куда девается последний байт) / 7 сообщений из 7, страница 1 из 1
26.12.2007, 19:49
    #35036347
Sergey Andriyasyan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать Stream через WCF? (или куда девается последний байт)
Как передать поток через WCF?
Я делаю так:
1. создаю MessageContract:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
[MessageContract]
public partial class MyFile
{
	private int lengths;
	private System.IO.Stream content;
	[MessageHeader]
	public int Lengths
	{
		get { return lengths; }
		set { lengths = value; }
	}
	[MessageBodyMember]
	public System.IO.Stream Content
	{
		get { return content; }
		set { content = value; }
	}
}
2. описываю OperationContract:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
[OperationContract]
void SetMyFile(MyFile file)
{
	byte[] bs = new byte[file.Lengths];
	int i = file.Content.Read(bs, 0, file.Lengths);
	//^^здесь i будет равно 3 а должно 4
}

3. на клиенте делаю так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
MyFile myFile = new MyFile();
System.IO.Stream str = new MemoryStream(4);
str.Write(new byte[] { 1, 2, 3, 4 }, 0, 4);

str.Seek(0, SeekOrigin.Begin);//-перехожу в начало буфера (готовлюсь к чтению)
myFile.Content = str;
myFile.Lengths = (int)myFile.Content.Length;
proxy.SetMyFile(myFile);
У чем моя ошибка? Подскажите пожалуйста! Отправляю 4 байта а приходит 3, если отправлю 500 придет 499, заранее спасибо!
...
Рейтинг: 0 / 0
26.12.2007, 20:13
    #35036379
Sergey Andriyasyan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать Stream через WCF? (или куда девается последний байт)
Прочитал 4-ый байт но только со второй попытки. С чем это может быть связано?
Код: plaintext
1.
2.
3.
4.
5.
6.
byte[] bs = new byte[4];
byte[] bs2 = new byte[4];
int i = stream.Read(bs, 0, 4); 
// i равно 3 bs содержит только 3 байта
int i2 = stream.Read(bs2, 0, 4);
// i2 равно 1 bs2 содержит 1 байт
...
Рейтинг: 0 / 0
27.12.2007, 09:04
    #35036737
Volhv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать Stream через WCF? (или куда девается последний байт)
Sergey AndriyasyanПрочитал 4-ый байт но только со второй попытки. С чем это может быть связано?
Код: plaintext
1.
2.
3.
4.
5.
6.
byte[] bs = new byte[4];
byte[] bs2 = new byte[4];
int i = stream.Read(bs, 0, 4); 
// i равно 3 bs содержит только 3 байта
int i2 = stream.Read(bs2, 0, 4);
// i2 равно 1 bs2 содержит 1 байт


возможно фрагментирование пакета
сделайте буфер с циклическим ожиданием всей длины пакета (догрузка) - у вас ета проблема отпадет
...
Рейтинг: 0 / 0
28.12.2007, 13:09
    #35039941
sergey_spb
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать Stream через WCF? (или куда девается последний байт)
Что значит циклическое ожидание? и означат ли это что проблема отпадет?
...
Рейтинг: 0 / 0
29.12.2007, 08:36
    #35041353
МихаилР
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать Stream через WCF? (или куда девается последний байт)
Сергей, а зачем так сложно?

Если Вам нужно передать только поток, то можно обойтись просто методом с одним параметром Stream. Если же очень нужно передавать доп. информацию в пакете, то можно просто обойтись полями класса (зачем для передачи городить свойства)?

Что же касается Вашей, проблемы, то я подозреваю, что дело в том, что вы пытаетсь с последовательным потоком работать как с потоком прямого доступа (используя Seek). Копировать лучше последовательно. Примерно так (при условии, что поток не пуст, конечно):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
        
public static void CopyStream(System.IO.Stream src, System.IO.Stream dst)
{
      const int buf_size = 10000;
      byte[] buf = new byte[buf_size];

      int cur_readed = 0;

      do
      {
          cur_readed = src.Read(buf, 0, buf_size);
          dst.Write(buf, 0, cur_readed);
      }
      while (cur_readed > 0);
}
...
Рейтинг: 0 / 0
29.12.2007, 10:03
    #35041462
Volhv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать Stream через WCF? (или куда девается последний байт)
вообще на будующее есть алгоритмы которые используются в сокетах для передачи данных

чтото вроде
блок 1-4 байта содержат код/тип пакета который может регламентировать длину пакета (не нужно вам)
или блок 4 байта содержит длину пакета данных (вам нужно)
далее идет блок данных с длиной пакета


от вас требуется только получить определенное количество байт (ожидать их прихода)
и постепенно коллекционировать их в свой буффер (порследовательно, потому что сокеты могут содержать произвольные длинны пакетов, но очередность зависит от протокола (UTP - может прийти пакеты 1,2,4,3,... а TCP - строго очередно 1,2,3,4,... ) ) ...

а дальше передавать их на обработку...
...
Рейтинг: 0 / 0
29.12.2007, 11:22
    #35041626
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать Stream через WCF? (или куда девается последний байт)
>Sergey Andriyasyan
>Как передать поток через WCF?
Если я правильно Вас понял, то может быть так ...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
//-- Сторона удаленого сервиса
//------------------------------
 namespace ns_MyFile {

   public interface IMyFile {
     void mdMyFile(byte[] bv);
   }
   ...
   //-- Сервис управления взаимодействием с клиентом
   public class ЦУС_Impl : MarshalByRefObject, IMyFile {
     ...
     byte[] IMyFile.mdMyFile(byte[] bv) {
       MemoryStream xms=null;
       try {
         xms=new MemoryStream(bv)
         ...
       }
       catch {...}		
     }		
     ...
   }
  
   //-- Сторона клиента
   //------------------------------
   [ServiceContract]
   public interface IMyFile {
     [OperationContract]
     void mdMyFile(byte[] bv);
   } 		

   ...
   try {
     //-- Получим ссылку на интерфейс
     ChannelFactory<ns_MyFile.IMyFile> factory = new ChannelFactory<ns_MyFile.IMyFile>(new NetTcpBinding());
     iMyFile = factory.CreateChannel(new EndpointAddress(...));
     ...
     MemoryStream xms=new MemoryStream....; 	
     ...
     byte[] xbb=xms.ToArray();
     //-- Может быть имеет смысл осуществить компрессию данных (xbb=Компресс(xbb))
     //-- и шифрование (xbb=Encrypt(xbb))
     iMyFile.mdMyFile(xbb);
     ...
   }
   catch{...}
   ...

 }
С уважением, Владимир.
...
Рейтинг: 0 / 0
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / Как передать Stream через WCF? (или куда девается последний байт) / 7 сообщений из 7, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]