Entwickler-Ecke

Internet / Netzwerk - Dateiübetragung abbrechen


Andidreas - Mo 25.12.06 18:57
Titel: Dateiübetragung abbrechen
Hallo
Wie kann/oder muß ich eine Dateiübetragung abbrechen, so das der Sever die schon empfangenen Bytes trotzdem als Datei schreibt?


Narses - Mo 25.12.06 19:04

Moin!

user profile iconAndidreas hat folgendes geschrieben:
Wie kann/oder muß ich eine Dateiübetragung abbrechen, so das der Sever die schon empfangenen Bytes trotzdem als Datei schreibt?

Das liegt im Ermessen der Serveranwendung, was sie mit den teilweise empfangenen Daten macht; würde mich wundern, wenn du überhaupt Einfluss darauf nehmen kannst. :?

cu
Narses


Andidreas - Mo 25.12.06 19:05

Der Server ist im Programm integriert. Kann also ohne Probleme ran.


Sascha999999999 - Mo 25.12.06 19:07

bei Indi giebt es binding disconnect, solten die Daten erhaltenbleiben.


BenBE - Mo 25.12.06 19:08

TCP bietet die Möglichkeit während der Übertragung eines Datenstroms sogenannte UrgentData-Pakete zu versenden. Diese werden prioretisiert von TCP übertragen und ordnen sich einfach in den Datenstrom ein. Mit Hilfe von Urgend Data ist es möglich, dem Empfänger selbst bei "verstopfter Leitung" mitzuteilen, dass er etwas bestimmtes tun soll (z.B. Empfangspuffer leeren). Wie das aber in den meisten Socket-Komponenten umgesetzt ist, weiß ich grad nicht .... Ich weiß nur, dass es TCP laut Spezifikation vorsieht und das einige Protokolle (z.B. Telnet und RLogin ;-)) auch nutzen.


Narses - Mo 25.12.06 19:16

Moin!

Wenn es deine Server-Anwendung ist, dann sende vom Client aus eine entsprechendes Kommando (ist dann ja auch dein Protokoll), was dem Server signalisiert, den Empfang abzubrechen, die Daten zu schreiben und dann aufzulegen, fertig. ;)

Ist es eine "fremde" Serveranwendung, ist das praktisch unmöglich sicherzustellen. :?

cu
Narses


Andidreas - Mo 25.12.06 19:25

Sehr schön. Stellt sich mir die Frage: welches Kommando?


Narses - Mo 25.12.06 19:33

Moin!

Woher soll ich dein Protokoll kennen? :roll: ;) Du hast ja nix darüber gesagt... :nixweiss:

cu
Narses


Andidreas - Mo 25.12.06 20:36

Das Ganze funktioniert per IdTCP.

Client:

Delphi-Quelltext
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:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
procedure TForm1.Senden(Datei: String);
Var
  fs: TFileStream;
  tmpMs: TMemoryStream;
  iTmpSize: Longint;
  iNextSize: Longint;
  bError: Boolean;
  sMsgToSvr: String;
  iSendTime: Cardinal;
  iTimeDiff: Cardinal;
  BytesperSek: Double;
  sCmd: String;
begin
  try
    fs := TFileStream.Create(Datei, fmOpenRead or fmShareDenyWrite);
  except
    MessageDlg(Datei + ' kann nicht geöffnet werden ! '+#10#13
    +'Wahrscheinlich ist diese Datei von einer anderen Anwendung geöffnet !',
    mtError,[mbok], 0);
    exit;
  end;
  btnSenden.Enabled := false;
  TCPClient.Disconnect;
  TCPClient.ConnectTimeout := 10000;
  TCPClient.Host := ed_ServerIP.Text;
  TCPClient.Port := 9876;
  try
    TCPClient.Connect();
  except
    Messagedlg('Es konnte keine Verbindung zum Server: ' +
    ed_ServerIP.Text + ' auf Port: 9876 hergestelt werden!', mtError,[mbok],0);
    bSendeFehler := true;
    btnSenden.Enabled := true;
    exit;
  end;
  if TCPClient.Connected then
  begin
    stb.Panels[1].Text := '';
    sMsgToSvr := inttostr(fs.size) + cSplitChar + ExtractFilename(Datei);
    TCPClient.IOHandler.WriteLn(sMsgToSvr);
    tmpMS := TMemoryStream.Create;
    try
      iFileSize := fs.Size;
      iTmpSize := 0;
      bError := false;
      fs.Position := 0;
      while (iTmpSize < iFileSize) and (not bError) do
      begin
        tmpMs.clear;
        Application.ProcessMessages;
        iSendTime := GetTickCount;
        try
          iNextSize := iFileSize - iTmpSize;
          if iNextSize > cFileSplitSize then
            iNextSize := cFileSplitSize;
          iTmpSize := iTmpSize + tmpMs.CopyFrom(fs,iNextSize);
          TCPClient.IOHandler.WriteBufferOpen;
          TCPClient.IOHandler.Write(tmpMS, 0, true);
          TCPClient.IOHandler.WriteBufferClose;
          iTimeDiff := GetTickCount - iSendTime;
          pBar.Position := Round(iTmpSize/iFileSize*100);
          pBar.Repaint;
          try
            BytesperSek := round(tmpMs.Size/1024/iTimeDiff*1000);
          except
            BytesperSek := 0;
          end;
          lab_Speed.Caption := 'Speed ' + FormatFloat('0.00',BytesperSek)+ ' KB/Sek.';
          lab_Speed.Repaint;
        except
          bError := true;
        end;
      end;
      try
        sCmd := TCPClient.IOHandler.ReadLn(#$A,7500);
      except
        sCmd := 'TimeOut-Error';
      end;
      TCPClient.Disconnect;
    finally
      tmpMs.Clear;
      FreeAndNil(tmpMs);
    end;
    if (not bError) and (sCmd = 'FILEOK'then
      stb.Panels[1].Text := 'Datei wurde erfolgreich versendet!'
    else
      stb.Panels[1].Text := 'Fehler beim versenden der Datei!';
  end;
  pBar.Position := 0;
  pBar1.Position := 0;
  lab_Speed.Visible := false;
  if iSound = 0 then
    PlaySound('SystemNotification'0, SND_SYNC);
end;


Server

Delphi-Quelltext
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:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
function TFileReceiver.Start : Boolean;
Var bError : Boolean;
    bReady : Boolean;
    fs     : TFileStream;
begin
  result := true;
  Form1.fLabRe.Visible := true;
  if Form1.cbxbeim_Senden.Checked then
  begin
    Form1.Tray.Active := true;
    Form1.Hide;
  end;
  if iFileSize > 0 then begin
    Form1.stb.Panels[1].Text := AThread.Connection.Socket.Binding.PeerIP +
    ' überträgt ' + sFileName;
    bError := false;
    bReady := false;
    iReceivedBytes := 0;
    sTemp := GenerateUniqueFileName(sFileName);
    sFileName := Form1.sVerzeichnis + '\' + sTemp;
    try
      fs := TFileStream.Create(sFileName, fmCreate or fmShareExclusive);
    except
      result := false;
      exit;
    end;
    try
      While (AThread.Connection.Connected) and
            (not bError) and (not bReady) do begin
        tmpMS.clear;
        try
          AThread.Connection.IOHandler.ReadStream(tmpMS);
          if tmpMS.Size > 0 then begin
            fs.copyFrom(tmpMS,0);
            iReceivedBytes := iReceivedBytes + tmpMS.Size;
          end;
          bReady := (fs.Size = iFileSize);
        except
          tmpMS.Clear;
          bError := true;
        end;
      end;
    finally
      fs.free;
      if bError then
        DeleteFile(sFileName);
      Form1.stb.Panels[1].Text := 'Datei komplett empfangen!';
    end;
    result := FileExists(sFileName);
    Form1.fLabRe.Visible := false;
  end;
  if Form1.cbxbeim_Senden.Checked then
  begin
    Form1.Tray.Active := false;
    Form1.Show;
  end;
end;


Narses - Mo 25.12.06 23:43

Moin!

Wie ich das sehe, verwendest du kein Protokoll für deine Datenübertragung bzw. Dateiübertragung. Dann kannst du natürlich kein Kommando senden, weil du ja gar keine Kommandos verwendest. :? Nun, ob das klug ist oder nicht, ist eine andere Frage, und die werde ich (hier) nicht beantworten.

Mach dich mal über ein Suche in: Delphi-Forum, Delphi-Library PROTOKOLL schlau, damit kommst du weiter. ;)

cu
Narses


Andidreas - Di 26.12.06 00:08

Was genau meinst Du mit Protokoll?


Narses - Di 26.12.06 00:11

Moin!

Damit meine ich, Steuerinformationen und Nutzdaten in einem Datenstrom gemeinsam unterzubringen und auf der Empfängerseite wieder zu trennen. Dann kannst du in deinen Nutzdatenstrom (Datei) z.B. die Steuerinformation "Abbruch" einbringen. Mehr unter dem Suchbegriff aus meinem letzen Beitrag. ;)

cu
Narses