Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Sockets: abgehenden Port bei Send festlegen?
Joltan
myCSharp.de - Member



Dabei seit:
Beiträge: 58
Herkunft: Exil-Badener

Themenstarter:

Sockets: abgehenden Port bei Send festlegen?

beantworten | zitieren | melden

Wie kann ich den abgehenden Port beim Versenden von UDP Nachrichten festlegen?
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Joltan,

ohne mich mit UDP wirklich auszukennen, ist mir folgendes ins Auge gesprungen:

protected Socket UdpClient.Client {get; set;}

Aus der Beschreibung: "Verwenden Sie den zugrunde liegenden Socket, der vom Client zurückgegeben wurde, wenn Sie mehr als den vom UdpClient bereitgestellten Zugriff benötigen." und "Use the Socket returned by Client to set an option that is not available using UdpClient."

Die Eigenschaft ist zwar protected, aber das ist ja keinen wirkliche Klippe.

HTH

herbivore
private Nachricht | Beiträge des Benutzers
Joltan
myCSharp.de - Member



Dabei seit:
Beiträge: 58
Herkunft: Exil-Badener

Themenstarter:

beantworten | zitieren | melden

Ahm, ich hätte vieleicht dazuschreiben sollen, daß ich nicht udpClient verwende, sondern direkt auf Sockets aufsetze (da ich den Timeout benötige der unverständlicherweise in der udpClient-Klasse nicht gesetzt werden kann):


int pingStart = 0;
string output = "";
try
{
	Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
	sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 2000);
	Byte[] sendBytes = new byte[32];
	sendBytes[0] = 0x20;
	// ...
	// Hier werden dann noch die anderen Bytes einzeln gesetzt
	// ...
	sendBytes[31] = 0x11;
	IPHostEntry serverHE = Dns.GetHostByName(this.Address);
	IPEndPoint RemoteIpEndPoint = new IPEndPoint(serverHE.AddressList[0], this.Port);
	EndPoint test = sock.;
	sock.SendTo(sendBytes, RemoteIpEndPoint);
	pingStart = System.Environment.TickCount; // Start timing
	Byte[] receiveBytes = new byte[434];
	EndPoint end = (EndPoint)RemoteIpEndPoint;
	try
	{
		int received = sock.ReceiveFrom(receiveBytes, ref end);
		char[] outchars = Encoding.UTF8.GetChars(receiveBytes, 0, received);
	}
	catch { }
	finally { sock.Close(); }
}
catch { }
finally
{	
	if (output != "") {this.PingReply = (System.Environment.TickCount - pingStart) + "ms";}
	else {this.PingReply = "";}
}
return output;
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

beantworten | zitieren | melden

Hallo!

Ist es nicht völlig Wurscht, welchen AUSGEHENDER Port verwendet wird? Viel wichtiger ist es, dass der eingehende auf dem Server richtig angegeben ist.

Normalerweise ist es so, dass Windows bei einer SocketAnfrage einen beliebigen Socket zurückliefert, auf dem dann die Daten übertragen werden.

Der Server bekommt das genauso mitgeteilt, und antwortet auf diesem dann zurück!

Bei der nächsten Übertragung das selbe...

Also in Stichworten so:

- SocketAnfrage auf bestimmten Port = Kommunikationsport.
- Bei Server liefert Windows den Datenport.
Bei Clients liefert Server den Datenport.
- Daten werden übertragen.
- Datenport wird geschlossen.
- Dann kann wieder eine datenanfrage bzw Datensendewunsch auf dem Kommunikationsport übermittelt werden.

Also wenn der ausgehende Port wegen einem Router oder Firewall wichtig ist, dann kann ich sagen, dass der ausgehandelte Datenport automatisch akzeptiert wird (aufgrund des Kommuniationsports!).

Ich hoffe das hilft weiter...

Übrigens verwende ich auch direkte Socketprogrammierung ->

Für ClientVerbindungen:

		#region Method OpenConnection
		/// <summary>
		/// Method to open a Server Connection.
		/// </summary>
		/// <returns>true if connection is succesful; false if connection fails.</returns>
		public bool OpenConnection()
		{
			if (!isServer)
			{
				SetErrorMessage("You tried to open a Server Connection for a Client Socket!");
				return false;
			}

			try
			{
				connSocket.Bind(new IPEndPoint(IPAddress.Loopback, port));
				connSocket.Listen(20); // I don´t know which queue for incoming connections is useful! For Vip no queue is necessary.
				receiveSocket = connSocket.Accept();
			}
			catch (SocketException serr)
			{
				string tmpString = "Socket Exception caught: " + serr.Message;
				SetErrorMessage(tmpString);
			}
			catch (Exception err)
			{
				string tmpString2 = "Code Exception caught [Method: public bool OpenConnection(string ipaddress)]. Error: " + err.Message;
				SetErrorMessage(tmpString2);
			}

			if (receiveSocket.Connected)
			{
                isConnected = true;
				return true;
			}
			else
			{
				isConnected = false;
				return false;
			}
		}


Für Serververbindungen:

		/// <summary>
		/// Method to open a Client Connection.
		/// </summary>
		/// <param name="ipaddress">string which includes the IP-Address in following format:
		/// 'nnn.nnn.nnn.nnn'. Preceding '0's should be leaved out.</param>
		/// <returns>true if connection is succesful; false if connection fails.</returns>
		public bool OpenConnection(string ipaddress)
		{
			if (isServer)
			{
				SetErrorMessage("You tried to open a Client Connection for a Server Socket!");
				return false;
			}

			try
			{
				connSocket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress) , port));
				receiveSocket = connSocket;
			}
			catch (SocketException serr)
			{
				string tmpString = "Socket Exception caught: " + serr.Message;
				SetErrorMessage(tmpString);
			}
			catch (Exception err)
			{
				string tmpString2 = "Code Exception caught [Method: public bool OpenConnection(string ipaddress)]. Error: " + err.Message;
				SetErrorMessage(tmpString2);
			}

			if (receiveSocket.Connected)
			{
				isConnected = true;
				return true;
			}
			else
			{
				isConnected = false;
				return false;
			}

		}
		#endregion


Viel Spaß damit...
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
Joltan
myCSharp.de - Member



Dabei seit:
Beiträge: 58
Herkunft: Exil-Badener

Themenstarter:

beantworten | zitieren | melden

Erstmal warum ich anfrage: Ich schreibe derzeit ein Tool, mit dem ich Gameserver überwachen kann (d.h. Spielerzahl, gerade gespielte Map, etc. abfragen). Da die betreffenden Server auf die üblichen GameSpy-kompatiblen Anfragen nicht antworten, aber der in das Spiel integrierte Gambrowser die entsprechenden Infos abfragen kann, habe ich mich dran gemacht dessen Abfrage-Mechanismus nachzubilden. Dabei habe ich festgestellt daß die Anfragen immer vom lokalen Port 2304 abgehen, egal welchen Port der Server benutzt. Meine Vermutung ist nun, daß der Server nur eingehende Verbindungen vom entsprechenden Port akzeptiert.

Es sollte also prinzipiell möglich sein den Port festzulegen - wie, das kann ich leider auch deinem Beispiel nicht entnehmen.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Joltan,

heißt das, dass wir dich beim Cheaten und/oder der Datenspionage unterstützen sollen? Nur eine Frage!

herbivore
private Nachricht | Beiträge des Benutzers
Joltan
myCSharp.de - Member



Dabei seit:
Beiträge: 58
Herkunft: Exil-Badener

Themenstarter:

beantworten | zitieren | melden

Erstmal: beim Spiel handelt es sich um 'Operation Flashpoint: Resistance', und eine erste Version meines Tools ist auf meiner OFP Webseite verfügbar. Nur damit hier nicht irgendwelche falschen Ideen aufkommen.

Das Tool soll es Spielern lediglich ermöglichen ihre Lieblingsserver zu 'überwachen', ohne dazu ständig mit Alt-Tab zwischen Spiel und Desktop hin-und-her zu wechseln und ohne ständig das (leicht ein paar hundert MB Ram verschlingende) Spiel ständig aktiv zu haben.

In der bestehenden Version habe ich bereits eine Buddylist, und die Möglichkeit eines Alarms bei Ende eines Spiels (so daß man der nächsten Runde rechzeitig vor Start beitreten kann) eingebaut, und - abgesehen von einem im DirectX-Teil dieses Forums geschilderten Problem - funktioniert dies auch einwandfrei für herkömmlich dezidierte OFP Server welche das übliche GameSpy-Verfahren (UDP-Request '\status\' auf Serverport +1) unterstützen.

Es gibt allerdings inzwischen eine neuere Version des Spiels namens VBS, welche die traditionellen GameSpy-Abfragen nicht mehr unterstützt - und genau die will ich eben auch abfragen. Primär aus Eigeninteresse, da ich beides spiele und es dafür noch kein vergleichbares Tool gibt.

Um den Server allerdings zu einer Antwort zu überreden muß ich ihn erstmal dazu bringen mein Paket nicht zu ignorieren - und das geht eben offensichtlich unter anderem nur wenn die Anfrage vom richtigen Port aus kommt. Daher meine Frage hier.
private Nachricht | Beiträge des Benutzers
Joltan
myCSharp.de - Member



Dabei seit:
Beiträge: 58
Herkunft: Exil-Badener

Themenstarter:

beantworten | zitieren | melden

*Bump*

Ist außer der Unterstellung etwas Illegales vorzuhaben vieleicht auch ein konstruktiver Hinweis zur erfragten Thematic zu haben? Wie gesagt, alles was ich bräuchte wäre ein Hinweis ob (und wenn ja, wie) ich in C# den abgehenden Port festlegen kann.
private Nachricht | Beiträge des Benutzers
Fabse
myCSharp.de - Member



Dabei seit:
Beiträge: 124

beantworten | zitieren | melden

ich hab da ne idee: du hast doch ein tool, was die daten bereits anzeigen kannst, von dem du sozusagen "abguckst" starte das 2 mal und guck dir bei der zweiten instanz an, ob die auch den gleichen clientport nutzt! vielleicht hast du ja auch woanders etwas falsch gemacht.
private Nachricht | Beiträge des Benutzers