| Autor |
Beitrag |
crush4
Hält's aus hier
Beiträge: 2
|
Verfasst: Sa 24.05.08 18:32
Moin leutz...
hab in der schule die aufgabe ein Email Client zu programmieren. Wir haben eine Socket klasse bekommen und sollen darauf aufbauen...
Eigentlich würde das prog schon ganz gut laufen... würden da nicht immer irgendwelche fehler kommen... Die fehler lassen sich nicht genau bestimmen, da sie immer unterschiedlich sind. Mal hengt sich das programm beim auflisten der mails auf und mal können mails nicht abgerufen werden. Ist irgendwie seltsam.
Nun ja ich würd mich freuen wenn ihr euch das prog mal angucken würdet und was dazu sagen könntet. Vielleicht wisst ihr ja auch woran die fehler liegen...
die socket klasse sieht so aus:
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: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153:
|
unit USocket;
interface
uses Windows, WinSock, SysUtils;
type Socket = class (TObject) private host: String; port: integer; socket: TSocket; public constructor create(host: String; port: integer); overload; constructor create(socket: TSocket); overload; function connect(): boolean; function dataAvailable(): integer; procedure write(b: integer); overload; procedure write(var b; len: integer); overload; procedure write(s: String); overload; function read(): integer; overload; function read(var b; len: integer): integer; overload; function readLine(): String; overload; procedure close(); end;
implementation
constructor Socket.create(host: String; port: integer); var wsa: WSADATA; begin self.port := port; self.host := host; WSAStartup(MAKEWORD(2,0), wsa); self.socket := winsock.socket(AF_INET, SOCK_STREAM, 0); end;
constructor Socket.create(socket: TSocket); begin self.socket := socket; end;
function Socket.connect(): boolean; var addr: SOCKADDR_IN; rc: integer; begin addr.sin_family := AF_INET; addr.sin_port := htons(self.port); addr.sin_addr.s_addr := inet_addr(PChar(self.host));
rc := winsock.connect(self.socket, addr, sizeof(SOCKADDR_IN));
result := rc <> SOCKET_ERROR; end;
function Socket.dataAvailable(): integer; const len = 1024; var b: array [0..1023] of char; begin result := recv(socket, b, len, MSG_PEEK); end;
procedure Socket.write(b: integer); var tmp: array[0..0] of char ; begin tmp[0] := char(b); send(socket, tmp, 1, 0); end;
procedure Socket.write(var b; len: integer); begin send(socket, b, len, 0); end;
procedure Socket.write(s: String); begin send(self.socket, s[1], length(s), 0); end;
function Socket.read(): integer; var tmp: array[0..0] of char ; begin recv(socket, tmp, 1, 0); result := integer(tmp[0]); end;
function Socket.read(var b; len: integer): integer; begin result := recv(socket, b, len, 0); end;
function Socket.readLine(): String; const LF = char($0A); var buffIn: array[0..255] of char; pos: integer; begin pos := -1; repeat inc(pos); recv(socket, BuffIn[pos], 1, 0); until (buffIn[pos] = LF); buffIn[pos] := char(0); result := String(buffIn); end;
procedure Socket.close(); begin end;
end. |
und mein programm sieht so aus:
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: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220:
| unit pop;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, USocket, StdCtrls, Buttons;
type TForm1 = class(TForm) Label1: TLabel; Label2: TLabel; Label3: TLabel; EHost: TEdit; EUser: TEdit; EPasswort: TEdit; BVerbinden: TButton; BTrennen: TButton; Memo: TMemo; EBefehl: TEdit; BListe: TButton; BAusfuehren: TButton; BHilfe: TButton; ListBox1: TListBox; Label5: TLabel; Bdel: TBitBtn; procedure BVerbindenClick(Sender: TObject); procedure BListeClick(Sender: TObject); procedure BHilfeClick(Sender: TObject); procedure BTrennenClick(Sender: TObject); procedure BAusfuehrenClick(Sender: TObject); procedure ListBox1Click(Sender: TObject); procedure BdelClick(Sender: TObject); private procedure Ausgabe(s: string); public end;
var Form1: TForm1; Sock: Socket; p: integer; email,s:string;
implementation
{$R *.dfm}
procedure TForm1.BVerbindenClick(Sender: TObject); var pophost: string; begin pophost:= '213.165.64.22'; Sock := Socket.create(pophost,110); if (EUser.Text <> '') and (EPasswort.Text <> '') then begin if (not Sock.connect) then begin Memo.Lines.Add('Error: Connection failed!'); end; Memo.Lines.add(sock.readLine); Memo.Lines.add(''); Sock.write('USER '+ EUser.Text+ chr(13) + chr(10)); Memo.Lines.add(sock.readLine); Memo.Lines.add(''); Sock.write('PASS ' + EPasswort.Text+ chr(13) + chr(10)); Memo.Lines.add(sock.readLine); Memo.Lines.add(''); Bliste.Enabled:= true; Btrennen.Enabled:= true; Bhilfe.Enabled:= true; Bausfuehren.Enabled:=true; Sock.write('STAT '+ chr(13) + chr(10)); s:= sock.readline; delete(s,1,4); p:= Pos(' ',s); email:= Copy(s,1,p-1); label5.Caption:='Sie haben'+' '+email+' '+'neue Emails'; end else Memo.Lines.Add('Daten vollständig eingeben'); end;
procedure TForm1.BListeClick(Sender: TObject); var i,a: integer; betreff,absender,zeile:string; begin
For i := 1 to StrtoInt(email) do begin Sock.write('RETR ' + InttoStr(i) + chr(13) + chr(10)); a:=1;
while Sock.dataAvailable > 3 do begin zeile:=sock.readLine; if Copy(zeile, 0, 8) = 'Subject:' then begin betreff:=Copy(zeile, 10, length(zeile)); end;
if Copy(zeile, 0, 5) = 'From:' then begin absender:=Copy(zeile, 10, length(zeile)); end end; zeile:=sock.readLine; If a = 1 then begin listbox1.Items.Add('From:'+' '+absender+' | '+'Betreff:'+' '+betreff); a:=0; end; end; end;
procedure TForm1.BHilfeClick(Sender: TObject); begin Ausgabe('Befehlsübersicht:'); Ausgabe('USER Name - Anmeldung mit '); Ausgabe('PASS Passwort - User-Name und Passwort'); Ausgabe('STAT - Status: Anzahl und Gesamtgröße der E-Mails'); Ausgabe('LIST - E-Mails nummerieren und Größen anzeigen'); Ausgabe('RETR # - E-Mail mit der Nummer # holen'); Ausgabe('DELE # - E-Mail mit der Nummer # löschen'); Ausgabe('NOOP - No Operation'); Ausgabe('RSET - Löschmarkierungen entfernen'); Ausgabe('QUIT - markierte E-Mails löschen und beenden'); end;
procedure TForm1.Ausgabe(s: string); begin Memo.Lines.Add(s); end;
procedure TForm1.BTrennenClick(Sender: TObject); begin Sock.write('QUIT '+ chr(13) + chr(10)); Sock.close; end;
procedure TForm1.BAusfuehrenClick(Sender: TObject); begin memo.Clear; Sock.write('EBefehl.Text '+ chr(13) + chr(10)); Memo.Lines.add(sock.readLine); end;
procedure TForm1.ListBox1Click(Sender: TObject); var Zahl : Integer; begin memo.Clear; Zahl := ListBox1.Itemindex; Sock.write('RETR ' + InttoStr(zahl) + chr(13) + chr(10)); while Sock.dataAvailable > 3 do begin Memo.Lines.add(sock.readLine); end; end;
procedure TForm1.BdelClick(Sender: TObject); var Zahl : Integer; begin Zahl:=listbox1.itemindex; Sock.write('DELE ' + InttoStr(zahl) + chr(13) + chr(10)); listbox1.DeleteSelected; end;
end. |
Moderiert von Gausi: Code- durch Delphi-Tags ersetzt
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Sa 24.05.08 23:32
Moin und  im Forum!
crush4 hat folgendes geschrieben: | | hab in der schule die aufgabe ein Email Client zu programmieren. Wir haben eine Socket klasse bekommen und sollen darauf aufbauen... |
Dieser WSA-Wrapper ist bestenfalls schlampig, vermutlich aber einfach nur fehlerhaft programmiert, die .Close-Methode hat ja nichtmal Inhalt...  (wenn Lehrer ohne didaktisches Geschick anfangen, Dinge "vereinfachen" zu wollen, dann wird´s leider fast immer ganz schlimm  ) Kurz: Wirf diese Unit auf den Müll und sag deinem Lehrer, dass der Code kaputt ist und man damit nix entwickeln kann, fertig.
Mein Tipp um da weiter zu kommen: nimm einen TClientSocket von den Borland-Standard-Kompos und stell ihn auf stBlocking, dann hast du wenigstens einen WSA-Wrapper, der funktioniert.
crush4 hat folgendes geschrieben: | | Eigentlich würde das prog schon ganz gut laufen... würden da nicht immer irgendwelche fehler kommen... |
Ah, das berühmte "es klappt schon alles, nur manchmal nicht"-Syndrom...
crush4 hat folgendes geschrieben: | | Die fehler lassen sich nicht genau bestimmen, da sie immer unterschiedlich sind. Mal hengt sich das programm beim auflisten der mails auf und mal können mails nicht abgerufen werden. |
Auch hier ist das nicht sonderlich verwunderlich, mal ein Beispiel aus deinem Code:
crush4 hat folgendes geschrieben: | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure TForm1.BVerbindenClick(Sender: TObject); var pophost: string; begin pophost:= '213.165.64.22'; Sock := Socket.create(pophost,110); if (EUser.Text <> '') and (EPasswort.Text <> '') then begin if (not Sock.connect) then begin Memo.Lines.Add('Error: Connection failed!'); end; Memo.Lines.add(sock.readLine); | |
Du machst nach einem fehlgeschlagenen Verbindungsversuch einfach weiter, statt hier abzubrechen. Das kann ja nicht gut gehen. Dazu kommt noch, dass viele Freehoster den Zugriff auf den POP-Account nur mit einem Zeitabstand wiederholt zulassen (irgendwas zwischen 5 und 15 Minuten ist üblich). Leider ziehen sich solche Dinge durch deinen ganzen Code, das wird so nix.
Auch hier noch ein Tipp von mir: schau dir mal dieses Tutorial an, damit du mal einen Einstieg in das ganze Thema Netzwerkkommunikation bekommst. Mit dem Weg deines Lehrers sehe ich da leider ziemlich schwarz...
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
crush4 
Hält's aus hier
Beiträge: 2
|
Verfasst: Mo 26.05.08 17:17
okay vielen dank für die antwort... habs dem lehrer mal gesagt aber das interessiert ihn nicht so xD
naja hab mein programm jetzt so einigermaßen gut hinbekommen und hab auch festgestellt, dass im postfach keine
Mails mit anhang, bildern usw liegen dürfen. Es dürfen lediglich text - mails sein
bis bald
crush4
|
|
|