Autor Beitrag
Käthe
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mo 07.03.11 17:45 
Bin ein wenig verwirrt was das Verhalten meiner Programme angeht. Vielleicht zur Infrastruktur:
In Unity3d läuft ein normales C# Skript auf einer Windows Plattform. Dieses soll über TCP mit einem Unix-Rechner Daten austauschen. Zur zeit stehe ich an einer Stelle, wo nur Daten von Windows zu dem Unix rechnen gesendet werden sollen:

Nun verwirrt mich folgendes:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
  TcpClient c = new TcpClient("entfernt",entfernt);
  Stream writer = c.GetStream();
    
  byte[] b = new byte[255];
  b[0] = 66;
    
  writer.Write(b, 0, b.Length);


Bei diesem Code läuft alles super, Unix-Server antowrtet mit
"B mit 20 Bytes" (Paket von 20 Bytes wurde empfangen, Inhalt B)

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
  TcpClient c = new TcpClient("entfernt",entfernt);
  Stream writer = c.GetStream();
    
  byte[] b = new byte[255];
  b[0] = 66;
  b[1] = 66;     <-
    
  writer.Write(b, 0, b.Length);


Hier geht es nun schief:
" mit 0 Bytes" Es wird nunmehr kein Paket, oder nur ein leeres Paket empfangen.

Der Unix Server wurde in C/C++ geschrieben:

ausblenden volle Höhe 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:
int main(int argc, char* argv[])
{

        char buffer[20];

        int listenFD = socket(AF_INET, SOCK_STREAM, 0);

        struct sockaddr_in saddr;
        saddr.sin_family = AF_INET;
        saddr.sin_port = htons(USEPORT);
        saddr.sin_addr.s_addr = htons(INADDR_ANY);

        if(bind(listenFD, (struct sockaddr*) &saddr, sizeof(saddr))<0)
                printf("Error while Binding\n");

        // Warte auf Clients
        if(listen(listenFD,10)<0)
                printf("Error while Listening\n");
        printf("Listening aktiviert\n");

        struct sockaddr_in simClient, evalClient, temp;
        int simFD, evalFD, tempFD;
        socklen_t len = sizeof(temp);

        tempFD = accept(listenFD, (struct sockaddr*) &temp, &len);
        printf("Client hat sich gemeldet\n");

        int num = recv(tempFD, buffer, sizeof(buffer), 0);
        printf("%s mit %d Bytes\n",buffer,num);

}


Weiterhin funktionieren die vorgeschlagenen Arten zur Senden von Strings, Quelle msdn.microsoft.com/d...ibrary/bb979208.aspx ebenfalls nicht. Verhalten ist hier wie die zweite gepostete C# Variante.

ausblenden Quelltext
1:
2:
3:
   Byte[] sendBytes = Encoding.ASCII.GetBytes ( time + "\r\n" );
          // Sende die Bytes zum Client
          outStream.Write ( sendBytes, 0, sendBytes.Length );


Nach Stunden wilden Rumprobierens schätze ich dass ich nun Hilfe brauche. Ich kann mir das Verhalten so nicht erklären.

Danke
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Mo 07.03.11 21:25 
Hallo,

also das, was ich auf den ersten Blick so sehe ist, dass in dem C/ C++ Programm ein fester Puffer von 20 Chars drin steht. Und dieser wird auch nicht in einer Schleife immer wieder neu gesetzt. Das bedeutet für mich, dass Du höchstens 20 Chars übertragen kannst. Da ich aber leider von C/ C++ sonst nicht wirklich viel Plan habe, weiß ich nicht, was das so für Auswirkungen hat.
Ich meine, Du überträgst ja immer die gesamte Länge des Array, also 255. Auch in dem Fall, dass nur das erste Byte einen Wert hat und alle anderen null ist die Länge ja trotzdem noch 255. Kann es sein, dass im C/C++ Programm ein Puffer-Überlauf erzeugt wird?

Kann aber auch gut sein, dass ich mit meiner Idee total daneben liege.
Marko
Käthe Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 08.03.11 10:37 
Daran hatte ich auch schon gedacht und im C# Programm mal einfach nur auf 20 Bytes reduziert (Bzw im C auf 255 erhöht). Hat leider nichts geholfen ...

Ich bin halt ein wenig ratlos, zudem ich an der Architektur eben nix machen kann. C# wäre für den Client nicht meine Wahl gewesen, ist aber in dem Sinne leider gefordert. Problem ist nur, dass ich mir mehr oder weniger während dieses Projektes C# komplett aneigne.
Käthe Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mi 09.03.11 11:16 
[GELÖST]

So Problem ist gelöst. Jetzt allerdings würde mich interessieren, warum ich diese Lösung nehmen muss:

Der Trick war in diesem Fall, dass die ersten 8 Bytes offensichtlich keine Daten enthielten. Das erste Byte war dabei für die Paketgröße ausschlaggebend, die Bedeutung der anderen kenne ich nicht.

Meine Daten fingen also erst ab Byte 9 an, wenn ich erst ab dort schreibe und lese läuft alles reibungslos

[FRAGE]

Offensichtlich werden nicht nur Daten in das gesendete Paket codiert, sondern auch ein kleiner Header. Dies sollte an sich aber nicht der Fall sein, oder? Das heißt ich muss wohl annehmen, dass meine Protokolle auf beiden Seiten nicht identisch sind, und nur durch Glück hab ich die Lösung finden. Vielleicht kann ja jemand erkennen, wo dieser Fehler ist, denn es ist nicht sehr schön, wenn ich bei allen Paketen immer diesen zusätzlichen Overhead habe.