WCF Streamed nur 2 Dateien

Meldur

Erfahrenes Mitglied
Hallo,

ich experimentiere gerade mit WCF herum und habe einen Service gebaut, der über BasicHttpBinding im transfereMode=Stremed Dateien beliebiger Größe übertragen soll. Solange ich nun Server und Client auf dem gleichen Rechner ausführe (nicht auf localhost, sondern der aktuellen Netzwerk-IP), schiebt er endlos viele Dateien hin und her. Wenn ich nun Server und Client auf jeweils einem Rechner habe, ist immer nach der 2. Datei (Download vom Server zum Client) Schluss. Der Server tut so, als hätte er die Anfrage gar nicht erhalten und der Client bricht irgendwann mit einem Timeout ab. Dabe scheint es keine Rolle zu spielen, wie groß die Dateien sind. Firewalls sind aus.

Hat jemand eine Idee?

Gruß,
Meldur
 
dann mal los...

hier die bindings und der service-aufruf des servers

Code:
<bindings>
      <!--Dateitransfere-Service-->
      <basicHttpBinding>
        <binding name="FileTransferServicesBinding" transferMode="Streamed" messageEncoding="Mtom" maxReceivedMessageSize="10067108864">
          <security mode="None">
            
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

Code:
 <!--Dateitransfere-Service-->
      <service behaviorConfiguration="MyServiceTypeBehaviors" name="SC3Server.FileTransferService">
        <endpoint address="mex" binding="basicHttpBinding" bindingConfiguration="FileTransferServicesBinding" contract="SC3NetworkInterface.IFileTransferService"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://2.0.0.2:8080/FileTranfer"/>
          </baseAddresses>
        </host>
      </service>

beim Client konfiguriere ich den Dienst zur Laufzeit:

Code:
System.ServiceModel.Channels.Binding ftBinding = new BasicHttpBinding();
                ((BasicHttpBinding)ftBinding).TransferMode = TransferMode.Streamed;
                ((BasicHttpBinding)ftBinding).MessageEncoding = WSMessageEncoding.Mtom;
                ((BasicHttpBinding)ftBinding).MaxReceivedMessageSize = 10067108864;
                EndpointAddress ea2 = new EndpointAddress("http://" + this.config.ServerIP + ":" + this.config.ServerFileTransferePort + "/FileTranfer/mex");
                ftClient = new FileTransferServiceClient(ftBinding, ea2);

Die Klasse FileTransfereServiceClient ist meine Interface-Klasse und beinhaltet Up- und Downloadroutinen.

Code:
 [ServiceContract]
    public interface IFileTransferService
    {
        [OperationContract]
        void UploadFile(RemoteFileInfo request);

        [OperationContract]
        RemoteFileInfo DownloadFile(DownloadRequest request);
    }

    [MessageContract]
    public class DownloadRequest
    {
        [MessageBodyMember]
        public string FileName;
    }

    [MessageContract]
    public class RemoteFileInfo: IDisposable
    {
        [MessageHeader(MustUnderstand = true)]
        public string FileName;

        [MessageHeader(MustUnderstand = true)]
        public long Length;

        [MessageBodyMember(Order = 1)]
        public System.IO.Stream FileByteStream;

        public void Dispose()
        {
            // close stream when the contract instance is disposed. this ensures that stream is closed when file download is complete, since download procedure is handled by the client and the stream must be closed on server.           
            if (FileByteStream!=null)
            {
                FileByteStream.Close();
                FileByteStream = null;
            }
        }
    }


dann hier noch ein Downloadaufruf vom Client:

Code:
 System.IO.Stream inputStream;
            long fileLength = this.TransfereClient.DownloadFile(ref this.currentDownloadFile, out inputStream);
            long allReaded = 0;

            // write server stream to disk
            using (System.IO.FileStream writeStream = new System.IO.FileStream(filePath, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write))
            {
                int chunkSize = 2048;
                byte[] buffer = new byte[chunkSize];

                do
                {
                    // read bytes from input stream
                    int bytesRead = inputStream.Read(buffer, 0, chunkSize);
                    allReaded += bytesRead;
                    if (bytesRead == 0) break;

                    // write bytes to output stream
                    writeStream.Write(buffer, 0, bytesRead);
                  

                   // report progress from time to time
                   Download_ProgressChanged(null, new StreamWithProgress.ProgressChangedEventArgs(allReaded, fileLength));

                } while (true);
            

                writeStream.Close();
            }


und zu guter letzt die Antwort-Routine vom Server:

Code:
public RemoteFileInfo DownloadFile(DownloadRequest request)
        {
            // get some info about the input file
            string filePath = this.serverFileRoot + request.FileName;
            System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);

            // report start
            Console.WriteLine("Sending stream " + request.FileName + " to client");
            Console.WriteLine("Size " + fileInfo.Length);

            // check if exists
            if (!fileInfo.Exists) throw new System.IO.FileNotFoundException("File not found", request.FileName);

            // open stream
            System.IO.FileStream stream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            this.activeDownloadStreams.Add(stream);

            // return result
            RemoteFileInfo result = new RemoteFileInfo();
            result.FileName = request.FileName;
            result.Length = fileInfo.Length;
            result.FileByteStream = stream;
            return result;

            // after returning to the client download starts. Stream remains open and on server and the client reads it, although the execution of this method is completed.
        }


ab der dritten Datei springt er die Server-Seite nicht mehr an - zumindest wird kein Haltepunkt ausgelöst.
 
Zurück