[C#.Net 1.1]Server anpingen (Socket Zugriff verweigert)

N

Nebulus Jones

Gast
Hi Leute!

Wäre super wenn mir jemand bei meinem Problem helfen könnte!

Zuerst zum Sinn meines Codes:
Es wird eine SMTP Serveraddresse reingegeben und es soll gecheckt werden, ob sie pingbar ist, wenn ja ist sie gültig. (Gibt es vielleicht eine bessere Methode, um soetwas zu überprüfen, bei der man keine Sockets benötigt?)

Meine Arbeitsumgebung:
Virtual Maschine mit Windows XP Prof., sitze also per remote am Entwicklungsrechner.

Da .NET1.1 ja keine Ping Klasse hat, hab ich mir eine ausm Netz besorgt. Diese funktioniert soweit auch ganz gut, bis zu dem Punkt an dem der Socket zum ersten Mal etwas senden soll. Dort bekomme ich den Error "Der Zugriff auf einen Socket war aufgrund der Zugriffsrechte des Sockets unzulässig".

Bei MSDN hab ich ein Workaround gefunden, indem man einen Registryeintrag hinzufügen muss (DisableRawSecurtiy = 1). Dies habe ich ausprobiert, glaube allerdings, dass dies nicht funktioniert, weil ich auf einer Virtual Mashine hocke. Also es geht nicht :)

Admin Rechte habe ich auch... Muss man vielleicht bei der Virtual Maschine irgendwelche Dinge konfigurieren um Sockets benutzen zu können?

Hier mal der Codeschnippsel:

Code:
Byte [] sendbuf = new Byte[ PacketSize ]; 
			//again check the packet size
			Index = Serialize(  
				packet, 
				sendbuf, 
				PacketSize, 
				PingData );
			//if there is a error report it
			if( Index == -1 )
			{
//				Console.WriteLine("Error in Making Packet");
				return false;
			}
	                
			dwStart = System.Environment.TickCount; // Start timing
			//send the Pack over the socket
			if ((nBytes = socket.SendTo(sendbuf, PacketSize, 0, epServer)) == SOCKET_ERROR) 
			{		
				return false;
			}

Ich weiß jetzt nicht ob das jetzt so hilfreich war... Fragt sonst einfach nach mehr ;)
 
Ich hab zwar noch nie ein Programm mit .NET gemacht, aber die Fehlermeldung hört sich an, als ob du keine Administratorrechte auf dem Computer hast.

Als Beispiel: Unter Linux dürfen normale Benutzer keinen Port unter 1024 öffnen. Da du offensichtlich versuchst den Server zu Pingen erwartest du ein Packet auf Port 7 (war doch ICMP Ping oder?).

Warum willst du den Server überhaupt pingen? Wäre es nicht sinnvoller einen Timeout bei der TCP-Verbindung zu setzen und den Fehler dort abzufangen?

Edit: Ich weis du hast geschrieben, dass du Administratorrechte hast, trotzdem riecht es für mich dannach.
 
Erstmal Danke für deine Antwort!

Genau, da die Fehlermeldung ja mit Rechten zutun hat, gehe ich davon aus, dass es mit der Virtual Maschine zusammen hängt auf der mein Visual Studio läuft. Vielleicht muss man da was an den Netzwerkeinstellungen vornehmen?!

Das Problem ist allerdings, dass das Programm out of the Box laufen muss, soll heißen das beim Kunden nichts am Server gemacht werden darf (Reg einträge ändern wäre ja die Hölle ;)). Und da man das mit solchen Adminrechten nie sicherstellen kann, muss ich von dem Socket gedöns wegkommen.

Also hat sich meine Frage aus dem 1. Posting erübrigt.

Warum willst du den Server überhaupt pingen?
Weil die Mail Send Methode vom .Net Framework keine Auskunft darüber gibt, ob der SMTP Server erreichbar war (Sie gibt void zurück). Der Benutzer soll darüber informiert werden, ob die Mail erfolgreich rausgegangen ist.

Ob die Account Daten richtig sind erfahre ich vom Server an dem sich der User anmeldet, das Authentifizieren spielt also eine Untergeordnete Rolle.

Wie läuft das mit dem TCP IP Timeout?
 
Zuletzt bearbeitet von einem Moderator:
Kurze Info vorweg: Egal wie du deine Mail über das Internet schickst, du wirst ohne Sockets nicht arbeiten können :) Auch der SmtpClient verwendet Sockets.

SMTP läuft über das TCP/IP Protokoll. Das ist ein Verbindungsorientiertes Protokoll, d.h. es muss zuerst eine Verbindung zum SMTP Server aufgebaut werden (3-Way-Handshake-Protocol) bevor Daten ausgetauscht werden. Das läuft grob skiziert wie folgt ab
  • Client sendet Datenpacket an Server mit dem Inhalt: Ich will eine neue Verbindung initalisieren, bitte um bestätigung
  • Server sendet Datenpacket an Client zurück: Verbindung ok, bitte um bestätigung
  • Client sendet Datenpacket an Server zurück: Ok

Erst nach dieser Prozedur werden bei TCP Datenausgetauscht. Der Datenaustausch erfolgt ausserdem Konsistent, es gehen also keine Packete unbemerkt verloren, da jedes empfangene Packet bestätigt wird. Dein Client sendet ein Datenpacket an den Server mit dem Wunsch eine Verbindung zu erstellen. Jetzt kannst du dem Client sagen, wie lange er auf eine Antwort warten soll. So tief musst du dich jedoch gar nicht mit der Materie beschäftigen - das macht .Net alles für dich.

Dein aktuelles Problem ist jedoch, dass die Methode SmtpClient::SendAsync() nur void zurückliefert. Das ist allerdings durch die Konzeption des Clients bedingt: Microsoft wollte erreichen, dass dein Programm weiterläuft und die E-Mail im Hintergrund versendet.
Wie ein Blick in die API Doku verrät, gibt es eine Möglichkeit die E-Mail nicht-asynchron zu versenden.
Die SmtpClient::send() Methode wirft eine Exception falls der Versand nicht erfolgreich ist:
SmtpException oder SmtpFailedRecipientsException.
 
Man ich hab mich schon soo gefreut...

Leider sind die Methoden die du auflistest für .Net 2.0, wir sind bei dem Kunden allerdings noch auf dem Framework 1.1.

Das ist eigentlich die ganze Misere... Beim 2.0er Framework wäre auch eine eigenständige Ping Klasse dabei, womit das Socketproblem aber wahrscheinlich auch noch nicht gelöst wäre ;)

Hast du vielleicht noch einen anderen guten Tipp für mich?
Aber erstklassige Antworten, danke :)

EDIT

Bin möglicherweise einen Schritt weiter:

Und zwar, wenn ich einen falschen smtp server angebe und die mail dann rausgehen soll wird eine exception geworfen "Auf das Objekt 'CDO.Message' konnte nicht zugegriffen werden.".

Was jetzt noch wichtig wäre ist, ob dieser Fehler nur auftritt, wenn der SMTP Server falsch ist. Hab das ein wenig probiert und es trat immer nur der Fehler auf.

Wenn es so ist, wäre damit eigentlich das Problem gelöst. Hoffe ich zumindest.

Ich teste noch ein bisschen weiter.

EDIT 2

Also Ich hab es jetzt geschafft 2 Fehlermeldungen zu bekommen.

Hintergrund
Ich sende mit der Mail einen Kalender-Anhang. Die Datei wird, bevor sie mit der Mail versendet wird in einem Verzeichnis auf dem Rechner zwischengespeichert, um nachdem versenden wieder gelöscht zu werden.

Fall 1 (smtp Server Addresse ist von mir absichtlich nicht richtig eingegeben)
Befindet sich bereits eine Datei mit dem selben Namen in dem Zwischenspeicherort bekomme ich die Fehlermeldung
"Der Prozess kann nicht auf die Datei "C:\\dummy\\test.vcs\" zugreifen, da sie von einem anderen Prozess verwendet wird."

Fall 2 (smtp Server Addresse ist von mir absichtlich nicht richtig eingegeben)
Ist der Zwischenspeicherort leer, bekomme ich die Meldung "Auf das Objekt 'CDO.Message' konnte nicht zugegriffen werden."

[LÖSUNG]

Während ich Edit 2 gerade geschrieben habe ist mir die Lösung praktisch in den Schoß gefallen :) Ich lasse trotzdem meine Gedankengänge mal so stehen, viellecht ist es für andere noch hilfreich.

Also wenn man sich die CDO.Message Exception mal in die Überwachung im Studio zieht und sich dort die "InnerException" ansieht kommt bei mir folgender Text zum Vorschein: "Der Transport konnte keine Verbindung zum Server herstellen."

Oh man, die Lösung war die ganze Zeit schon da... hm naja hier noch die Ressource, wie ich letzten Endes auf die Lösung gestoßen bin:

http://www.systemwebmail.com/faq/4.2.3.aspx

Dort wird alles Haarklein erklärt.

Enigma, nochmals Danke für deine Unterstützung!
 
Zuletzt bearbeitet von einem Moderator:
Zurück
Oben