Laden...

Socket: Asynchrones Senden über WAN-IP schlägt fehl.

Erstellt von 3r0rXx vor 9 Jahren Letzter Beitrag vor 9 Jahren 3.174 Views
3r0rXx Themenstarter:in
55 Beiträge seit 2014
vor 9 Jahren
Socket: Asynchrones Senden über WAN-IP schlägt fehl.

Hallo Forum,
ich habe mich letzthin registriert, weil ich ein seltsames Phänomen reproduziert habe, und ich nun nach der Lösung des Problems suche.

Und zwar nutze ich die asynchrone Sende-Methode der Socket-Klasse, gemeint ist;
.begin(-Write, -Connect, -Receive) --- .end(-Write, -Connect, -Receive);

Das Problem nun ist, dass das Senden über die WAN-IP trotz Portforwarding fehlschlägt, beziehungsweise, der Server keine Zeichenfolge akzipiert(-akzipieren(empfangen))

Ich nutze das Beispielvon MSDN :
Asynchrones Client-Socket-Beispiel

welches ich leicht modifiziert habe:


using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.Drawing;
using System.IO;

// State object for receiving data from remote device.
public class StateObject
{
    // Client socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 256;
    // Receive buffer.
    public byte[] buffer = new byte[BufferSize];
    // Received data string.
    public StringBuilder sb = new StringBuilder();
}

public class AsynchronousClient
{
    // The port number for the remote device.
    private const int port = 8000;

    // ManualResetEvent instances signal completion.
    private static ManualResetEvent connectDone =
        new ManualResetEvent(false);
    private static ManualResetEvent sendDone =
        new ManualResetEvent(false);
    private static ManualResetEvent receiveDone =
        new ManualResetEvent(false);

    // The response from the remote device.
    private static String response = String.Empty;

    private static void StartClient()
    {
        // Connect to a remote device.
        try
        {
            // Establish the remote endpoint for the socket.
            // The name of the 
            // remote device is "host.contoso.com".

            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("192.168.0.200"), port);

            // Create a TCP/IP socket.
            Socket client = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);

            // Connect to the remote endpoint.
            client.BeginConnect(remoteEP,
                new AsyncCallback(ConnectCallback), client);
            connectDone.WaitOne();

            // Send test data to the remote device.

            Send(client, "LoL-Rofl");
            sendDone.WaitOne();

            // Receive the response from the remote device.
            Receive(client);
            receiveDone.WaitOne();
            
            // Write the response to the console.
            Console.WriteLine("Response received : {0}", response);

            // Release the socket.
            client.Shutdown(SocketShutdown.Both);
            client.Close();

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void ConnectCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.
            Socket client = (Socket)ar.AsyncState;

            // Complete the connection.
            client.EndConnect(ar);

            Console.WriteLine("Socket connected to {0}",
                client.RemoteEndPoint.ToString());

            // Signal that the connection has been made.
            connectDone.Set();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void Receive(Socket client)
    {
        try
        {
            // Create the state object.
            StateObject state = new StateObject();
            state.workSocket = client;

            // Begin receiving the data from the remote device.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the state object and the client socket 
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;

            // Read data from the remote device.
            int bytesRead = client.EndReceive(ar);

            if (bytesRead > 0)
            {
                // There might be more data, so store the data received so far.
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                // Get the rest of the data.
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
            else
            {
                // All the data has arrived; put it in response.
                if (state.sb.Length > 1)
                {
                    response = state.sb.ToString();
                }
                // Signal that all bytes have been received.
                receiveDone.Set();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void Send(Socket client, string data)
    {
        // Convert the string data to byte data using ASCII encoding.
        byte[] byteData = Encoding.ASCII.GetBytes(data);
        // Begin sending the data to the remote device.
        client.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), client);
    }

    private static byte[] Image2ByteArray(Image Bild, System.Drawing.Imaging.ImageFormat Bildformat)
    {
        System.IO.MemoryStream MS = new System.IO.MemoryStream();
        Bild.Save(MS, Bildformat);
        MS.Flush();
        return MS.ToArray();
    }


    private static void SendCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.
            Socket client = (Socket)ar.AsyncState;

            // Complete sending the data to the remote device.
            int bytesSent = client.EndSend(ar);
            Console.WriteLine("Sent {0} bytes to server.", bytesSent);

            // Signal that all bytes have been sent.
            sendDone.Set();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    public static int Main(String[] args)
    {
        StartClient();
        return 0;
    }
}

//Code from http://msdn.microsoft.com/de-de/library/bew39x2a.aspx

Über die lokale IP funktioniert es wunderbar, es verbindet und sendet.

Über die WAN-IP verbindet es sich auch(!) jedoch empfängt der Server(hercules_3-2-8.exe) kein byteArray...

Hoffe auf Ratschläge!

Danke...

'Tis not too late to seek a newer world.

1.696 Beiträge seit 2006
vor 9 Jahren

Hallo,

was sagt Firewall log? Ich vermute mal dass es an der Firewall festhängt.

Grüße

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

3r0rXx Themenstarter:in
55 Beiträge seit 2014
vor 9 Jahren

Hey, wie es scheint liegt es nicht an der FireWall, denn ich deaktivierte es temporär,
letztendlich wird erfolgreich verbunden, jedoch werden keine Daten empfangen/gesendet...

Sehr suspekt..

Gruß.

'Tis not too late to seek a newer world.

1.696 Beiträge seit 2006
vor 9 Jahren

Hallo,

ich meine aber nicht die lokale FW von Windows, sondern die WAN-FW, sag aber nicht dass ihr keine FW zwischen WAN-Verkehr habt 😉. In der FW müßte man sehen können, ob und wie die Daten zum Ziel ablaufen, ob sie geblockt oder durchgelassen wurden. Es könnte sein dass für Handshake einen anderen Port verwendet wird und somit bei Datentransfer geblockt wird.

Grüße

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

W
955 Beiträge seit 2010
vor 9 Jahren

Hallo,

vllt mit Wireshark mal den Verkehr mitschneiden.

3r0rXx Themenstarter:in
55 Beiträge seit 2014
vor 9 Jahren

Wie schon erwähnt..
Ich habe Portforwarding genutzt und den Port 8000 freigeschaltet...
Durch diesen Vorgang ist es mir nun möglich, auf Port 8000 zu lauschen
ergo,
sende ich ein byte array synchronisiert, so empfängt der Server vollständig den byte array,
nutze ich nun die asynchrone Methode, so kann sich der Client noch immer verbinden(!), der Server jedoch empfängt kein byte array...

Und ja ( ;, ich habe eine WAN-FW, haha...

Gruß-

'Tis not too late to seek a newer world.

W
872 Beiträge seit 2005
vor 9 Jahren

Wo wird denn der Socket noch benutzt?
TCP ist nicht fire and forget, d.h. ein Schliessen des Sockets kann die gesendeten Bytes quasi überholen. Allgemein sollte der Client ein Acknowledge senden, damit Du diese Race-Condition verhindern kannst.

3r0rXx Themenstarter:in
55 Beiträge seit 2014
vor 9 Jahren

Ha! hm...
Ich habe das Problem auch im synchronen TCP-Client reproduzieren können...

Ich weiß nun aus welchem Grund der Server keine Daten empfängt.

=>
Ich hatte den Client synchronisiert rekonstruiert...
Der Client agierte exakt wie der asnychrone Client...
Eine Zeichenfolge war möglich über die WAN-IP zu versenden(!)..

Jedoch war es nicht möglich ein byte Array der Länge 2048 über den BinaryWriter in den Stream zu schreiben.
Die Lösung des Problems war nun, vor dem Versand, die TcpClient-Classe neu zu
instanziieren und den aktuellen Stream in den BinaryWriter zu laden das byte Array zu schreiben und den BinaryWriter zu schließen,
voila..
es klappt...
Problematisch nur, dass über 30 Verbindungen verknüpft und geschlossen werden...

Wie vbprogger schon erwähnte, liegt es am WAN-FW.
Dieser blockiert die Anfrage trotz Freischaltung.
Doch stelle ich massiv Verbindungen zum Server her, sendet es..
auch über WAN..

Hat jemand einen anderen Lösungsweg?

'Tis not too late to seek a newer world.

1.696 Beiträge seit 2006
vor 9 Jahren

Wie vbprogger schon erwähnte, liegt es am WAN-FW.
Dieser blockiert die Anfrage trotz Freischaltung.
Doch stelle ich massiv Verbindungen zum Server her, sendet es..
auch über WAN..

Hat jemand einen anderen Lösungsweg?

Also, die FW blockt ja nicht grundlos, es ist eine dumme Machine und tut nur das was man einstellt. Hast du in live log nachgeguckt, warum (nach welchen Regel) der Trafic geblockt wurde? Denn da kannst du bzw. euer Netzwerkadmin anfangen zu schrauben 😃

Grüße

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

3r0rXx Themenstarter:in
55 Beiträge seit 2014
vor 9 Jahren

oh...
Ursache eventualiter geklärt...

"","DHCP: Client receive ACK from ***, IP=***, Lease time=5400."
06:04:41  ","Remote management is disabled."
06:04:41  ","Block WAN PING is disabled.

Der Bildversand gilt als ATTACK...
Aus diesem Grunde wird nicht der ganze byte array empfangen...

Weiß jemand um Rat?
Ist es möglich im Router eine Priorität zu setzen?

Danke...

'Tis not too late to seek a newer world.

A
350 Beiträge seit 2010
vor 9 Jahren

Wo siehst du ein ATTACK ? Ich sehe ein ACK ein acknowledge

1.696 Beiträge seit 2006
vor 9 Jahren
"","DHCP: Client receive ACK from ***, IP=***, Lease time=5400."  
06:04:41  ","Remote management is disabled."  
06:04:41  ","Block WAN PING is disabled.  

Aus diesem Log kann man nicht viel sehen. Ich sehe weder Attack noch ein Blocking der Anfrage!

Grüße

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

3r0rXx Themenstarter:in
55 Beiträge seit 2014
vor 9 Jahren
Per-source UDP Flood Attack Detect (ip=MYIP) Packet Dropped
Whole System UDP Flood Attack from WAN Rule:Default deny
Whole System ACK Flood Attack from WAN Rule:Default deny

So,
das ist der folgende Log-Eintrag..

'Tis not too late to seek a newer world.

1.696 Beiträge seit 2006
vor 9 Jahren

Ah ha, dein Programm verwendet offensichtlich UDP anstatt TCP und freigegeben hast du aber TCP, daher werden Daten geblockt. Ich würde sagen, dass du anstatt

Socket client = ...

in

TcpClient client = ...

änderst, dann sollte es klappen.

Grüße

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

3r0rXx Themenstarter:in
55 Beiträge seit 2014
vor 9 Jahren

Ja tut es ^^+...
Danke!

Jedoch ist nun eine weitere Problematik entstanden...
Ich kann nun 2048 Lange byte arrays über das Internet senden 😁 ,jedoch muss ich mehrmals die TCP-Klasse instanziieren...und verbinden.

Stellt dies eine Gefahr da?
Denn versuche ich mit der Ursprungsverbindung die Daten zu senden, gilt dies als Angriff, sende ich jedoch, in dem ich die TCP-Klasse neu insanziiere und verbinde, verläuft dieses ohne großer Problematik.
Jedoch werden so über 89 Verbindungen hergestellt und wieder geschlossen,
ergo die Funktion wird 89 Mal aufgerufen..

Etwa so:

       
            this.tcpClient = new TcpClient();
            this.tcpClient.Connect(IPAddress.Parse(this.IP), this.Port);
            binaryWriter = new BinaryWriter(this.tcpClient.GetStream());
            binaryWriter.Write(_array);
            binaryWriter.Flush();
            binaryWriter.Close();

Viele Grüße

'Tis not too late to seek a newer world.

1.696 Beiträge seit 2006
vor 9 Jahren

Hm ... bei UDP versendet man byte array, aber bei TCP wird normalerweise gestreamt, warum machst du das nicht? Denn bei Streaming wird die Connection solange gehalten bis das Ende des Streams erreicht ist, ohne dass du was tun musst - und daher wird auch nicht als Attack von der FW interpretiert.

Grüße

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

3r0rXx Themenstarter:in
55 Beiträge seit 2014
vor 9 Jahren

OMG...

Es funktioniert...
Danke ( =...

Das rekonstruieren des Bildes scheint noch defektiv zu sein..
doch dessen Ursache ist mir schon bekannt!

DANKEEEE

'Tis not too late to seek a newer world.

3r0rXx Themenstarter:in
55 Beiträge seit 2014
vor 9 Jahren

Juppi;
nun wird das Bild dementsprechend konvertiert,
das Resultat:

Viele, vielen Dank...

Hinweis von MrSparkle vor 9 Jahren

Bild angehängt, siehe [Hinweis] Wie poste ich richtig?, Punkt 6.1

'Tis not too late to seek a newer world.