www.mikrocontroller.net

Forum: PC-Programmierung Datenübertragung über TCP Socket von c auf java


Autor: BUBU (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
ich versuche schon seit geraumer zeit einen TCP/IP socket in c zu 
erstellen der einfach einen unsigned char mit write wegsendet und dieser 
dann mit einem java client empfangen wird.
Das funktioniert auch alles sehr gut bis auf wenn ich einen unsigned 
char größer 127 wegsenden will kommt mir immer auf der java seite die 
Zahl 253 heraus. also für alle werte größer 7 bit ein konstanter wert :(

der c seitige code:
unsigned char g_valid_message[LENGTH_BIG_PACKET];


void inittcpsocket()
{
     struct sockaddr_in serv_addr;

     sock = socket(AF_INET, SOCK_RAW, 0);
     if (sock < 0) 
        BailOut("SOCKET: Opening socket error!");
     
     bzero((char *) &serv_addr, sizeof(serv_addr));

     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(g_port);
     
     if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
       BailOut("SOCKET: binding error! Maybe the port is used by an other application!");
       
     fprintf(stderr,"TCP-Socket configured! Program is listening on port = %d \n", g_port);
}

void *sendwithtcpsocket( void *arg )
{
  int clilen, newsockfd,n,i,length;
  struct sockaddr_in cli_addr;
  unsigned char recvbuf[2];
  
  listen(sock,5);
    clilen = sizeof(cli_addr);
  
  while (TRUE) 
  {
       newsockfd = accept(sock, (struct sockaddr *) &cli_addr, &clilen);
       if (newsockfd < 0) 
          BailOut("ERROR on accept");
       
       while(TRUE)
       {
         bzero(recvbuf,2);
         n = read(newsockfd,recvbuf,255);
         if (n < 0) 
         {
           fprintf(stderr,"ERROR reading from socket");
           break;
         }
         
         printf("Here is the message: %d %d\n",recvbuf[0],recvbuf[1]);
         if(recvbuf[0]==0)  /* end condition */
           break;
         
         if(g_bigreceived==TRUE)  /* get size of package */
      {
        length=LENGTH_BIG_PACKET;
        g_bigreceived=FALSE;
      }
      else
        length=LENGTH_SMALL_PACKET;
         
         n = write(newsockfd,g_valid_message,length);
         if (n < 0) 
         {
           fprintf(stderr,"ERROR writing to socket");
           break;
         }
       }
     } /* end of while */
}

der java seitige teil
public class TcpConnection {  
  private int length = 0;
  
  private Socket socket = null;
  private PrintWriter out = null;
    private BufferedReader in = null;
  
  public TcpConnection(String host, int port)
  {    
    try {
      socket = new Socket();  
      socket.connect(new InetSocketAddress(host, port));
      
      out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      
      socket.setSoTimeout(2000);
      
    } catch (IOException e) {
      e.printStackTrace();
      System.err.println("Socket creating ERROR: " + e.getMessage());
    }
  }
  
  public short[] receiveData()
  {
    byte number = 0;
    short[] result = receiveData(number);
    
    return result;
  }
  
  public short[] receiveData(byte number)
  {
    char[] buffer = new char[210];
    
    try {
      //write welcome message
      out.println(number);
      
      //get response
      length = in.read(buffer);

    } catch (IOException e) {
      System.err.println("ERROR reading from TCP-Socket: " + e.getMessage());
    }
    
    short[] data = unsignedconverter(buffer);
       
      return data;
  }
  
  /**
   * returns the length of the current packet
   * @return
   */
  public int getLength()
  {  
    return length;
  }
  
  public void closeConnection()
  {
    if(socket != null)
    {
      try {
        socket.close();
      } catch (IOException e) {
        System.err.println("ERROR closing TCP-Socket: " + e.getMessage());
      }
    }
  }
  
    /**
     * Converts a char array into a unsinged short array
     * @param input
     * @return
     */
    private short[] unsignedconverter(char[] input)
    {
      short[] result = new short[input.length];

        int firstByte = 0;
    
        for(int i=0; i<input.length;i++)
        {
          firstByte = (0x000000FF & ((int)input[i]));
          result[i] = (short)firstByte;
        }
        
      
      return result;
    }


ich glaube eher das der fehler sich irgendwo auf der c seite befindet... 
kann ja sein das ein normales write() hier den unsigned char in einen 
singed umwandelt... jedoch wäre das dann nicht die erklärung für den 
immer konstanten wert von 253

bitte um hilfe danke :)

Autor: Stefan S. (dangermouse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Derzeit habe ich ein ähnliches Projekt vor mir. Ich schreibe einen 
SocketServer in Java und muss mit C-Clients umgehen können.

Im "Java Kochbuch" von O'Reilly befindet sich ein hinweis, dass man auf 
C-Seite Network-Byte-Order-Macros verwenden sollte. Zur Datenübertragung 
gibt es da wohl Makros in den Internet Header Dateien oder in 
<machine/endian.h>

Auf Java-Seite lässt sich das ganze dann mittels DataInputStream lesen.
Als Beispiel hat der Autor eine C-Implementierung angegeben, die die 
entsprechenden Makros verwendet und eine Datei mit zufälligen Werten 
füllt. Der Code kann aber auch für Netzwerksockets verwendet werden.

http://javacook.darwinsys.com/javasrc/io/WriteRandom.c

Viele Grüße

Stefan

Autor: Markus V. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sagt mal, hat hier irgend eine (Schul-)Klasse dies als Hausaufgabe 
bekommen?? Es sind jetzt schon deren drei...

@BUBU
schau doch mal unter Beitrag "Daten per C++ an Java-Programm: Java-Typenproblem?" ( Daten 
per C++ an Java-Programm: Java-Typenproblem? )

Grüße
Markus V.

Autor: Johannes Slotta (johanness)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist zwar schon ne Weile her, dass ich in Java Netzwerkprogramme 
geschrieben habe (und selbst da ging nur Klartext übers Netz), aber sind 
Reader/Writer wirklich sinnvoll? Wenn ich mich recht entsinne waren die 
eher für Klartext denn für Binärdaten gedacht. Wie gesagt, schon ewig 
her, bin ein wenig aus der Übung...

Autor: Maik Ritter (kiamur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich bin mir nicht sicher, ob meine Antwort dir weiterhelfen wird, aber 
es könnte daran liegen, dass Java einfach keine 'unsigned' Typen kennt. 
Möchte man dennoch unsigned Typen verwenden, so kann man sich ja mal 
diesen Workaround anschauen, der mir bei der Problematik auch schon mal 
die Augen geöffnet hat: 
>http://darksleep.com/player/JavaAndUnsignedTypes.html <.

Wie gesagt, ich weiß nicht so recht, ob ich dein Problem überhaupt 
richtig verstanden habe, aber dieses 'unsigned'-Problem bei Java hat 
mich halt aufhorchen lassen.

Gruß
Maik

Autor: Johannes Slotta (johanness)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs noch mal nachgelesen, Reader/Writer ist wirklich für Texte gedacht, 
darum auch beim BufferedWriter das newLine(), das immer den für die 
Plattform richtigen Zeilenvorschub generiert :)

Wenn man ein Problem mit signed/unsigned hat, dann bekommt man im 
Fehlerfall eine Differenz zwischen richtigem und falschem Wert, die 
einer Zweierpotenz entspricht (2^8, 2^16, 2^32 oder 2^64, je nach Länge 
des Integers), Stichwort "Zweierkomplement". Der beschriebene Fehler 
(mehrere Zeichen werden auf eine bestimmte Zahl abgebildet) sieht eher 
so aus, als habe der Reader versucht, die Zeichen als Text zu 
interpretieren und verschiedene Zeichen als "unbekannt" gelesen 
(vielleicht weil sie nicht im 7-bit-Standard-ASCII drin sind). Habe 
leider gerade kein JDK hier installiert, um das schnell zu testen...

Wäre schön, wenn BUBU mal schreiben könnte, obs inzwischen läuft, was 
ihm dabei geholfen hat, und falls es nicht läuft, wie das Problem 
inzwischen aussieht.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.