Laden...

Dateiübertragung

Erstellt von alf468 vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.454 Views
A
alf468 Themenstarter:in
196 Beiträge seit 2005
vor 17 Jahren
Dateiübertragung

Erst einmal ein frohes Neues Jahr an alle.

Ich versuche mich gerade an der Dateiübertragung übers Netzwerk. Der Server kann mehrere Client Verbindungen speichern und verarbeiten. Eigentlich ist der Server eine Art Chatserver. Der Client verbindet sich und der Stream wird in einer Hashtable gespeichert. Eine Schleife durchläuft dann immer die Hashtable und führt die entsprechenden Aufgaben aus. Als kleines Feature wollte ich die Dateiübertragung hinzufügen.
Nun könnte es aber auch sein das mehrere Clients gleichzeitig Daten empfangen bzw. senden. Der Server bekommt erst einmal eine Info das eine Dateiübertragung gestartet wird. Da ich für die Dateiübertragung keinen neuen Port benutzen will sondern die bereits vorhandene Verbindung kam ich auf die Idee einen neuen Thread zu starten. Dieser Thread soll dann die Dateiübertragung durchführen. Es hätte also jeder Client für die Dateiübertragung einen eigen Thread. Das Problem ist aber wenn der Client nun unerwartet die Verbindung beendet. So wie ich das mit der Dateiübertragung gelöst habe wartet der Server immer auf Daten ohne ein Timeout.

protected override void Transfer(System.Net.Sockets.NetworkStream ns)
        {
            this.tns = ns;
            this._TransferThread = new System.Threading.Thread(new System.Threading.ThreadStart(Startransfer));
            this._TransferThread.Start(); //Dateiübertragung beginnen
        }

private void Startransfer()
        {
            Stream fileStream=null;
            try
            {
                int offset = 0;
                int size = 1024;
                byte[] buffer = new byte[size];
                long bytesRead = 0;
                string file = ((FileTransferObject)this._openTransfers[tns]).getName;
                int fsize = ((FileTransferObject)this._openTransfers[tns]).getSize;
                int start = ((FileTransferObject)this._openTransfers[tns]).getStart;
                this._openTransfers[tns] = null;
                if (start != 0)
                {
                    fileStream = new System.IO.FileStream(rootpath + "\\" + file, FileMode.Append);
                    //fileStream.Seek(start, SeekOrigin.Begin);
                    bytesRead = start;
                }
                else
                {
                    fileStream = new System.IO.FileStream(rootpath + "\\" + file, FileMode.Create);
                }
                do
                {
                    if (fsize - bytesRead < size)
                    {
                        size = (int)(fsize - bytesRead);
                    }
		    bytesReadOld = bytesRead;
                    bytesRead += this.tns.Read(buffer, 0, size);
                    fileStream.Write(buffer, 0, (int)(bytesRead - bytesReadOld));
                   
                    offset += size;

                } while (tns.CanRead && bytesRead < fsize);
                fileStream.Close();
                this._openTransfers.Remove(tns);
                this._TransferThread.Join();
                this._TransferThread = null;
            }
            catch (Exception e)
            {
                if (fileStream != null)
                    fileStream.Close();
                System.Diagnostics.Debug.WriteLine(e);
                this.RemoveClient(tns);
                this._TransferThread.Join();
                this._TransferThread = null;
            }
        }
 

Wenn der Client nun die Verbindung beendet, bleibt der Server in der Schleife obwohl nix mehr gelesen werden kann.
Warum merkt der Server in dem Moment nicht das er gar nicht mehr lesen kann ?
Das ganze funktioniert im Moment auch nur für einen Client aber ich wäre die Threads dann in einer Hashtable speichern. Ist das eine halbwegs gute Lösung ?

B
1.529 Beiträge seit 2006
vor 17 Jahren

MSDN:

NetworkStream.ReadTimeout Property
...
Gets or sets the amount of time that a read operation blocks waiting for data.
...
public override int ReadTimeout { get; set; }
...
Property Value
A Int32 that specifies the amount of time, in milliseconds, that will elapse before a read operation fails. The default value, Infinite, specifies that the read operation does not time out.
...
Exceptions
...
ArgumentOutOfRangeException The value specified is less than or equal to zero and is not Infinite.
...
Remarks
If the read operation does not complete within the time specified by this property, the read operation throws an IOException.
...
Note
This property affects only synchronous reads performed by calling the Read method. This property does not affect asynchronous reads performed by calling the BeginRead method.

Bitte immer erst die Doku zu einer Klasse durchlesen...