Datenübertragung über TCP Socket von c auf java

Gast #603529
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:
1
unsigned char g_valid_message[LENGTH_BIG_PACKET];
2

3

4
void inittcpsocket()
5
{
6
     struct sockaddr_in serv_addr;
7

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

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

24
void *sendwithtcpsocket( void *arg )
25
{
26
  int clilen, newsockfd,n,i,length;
27
  struct sockaddr_in cli_addr;
28
  unsigned char recvbuf[2];
29
  
30
  listen(sock,5);
31
    clilen = sizeof(cli_addr);
32
  
33
  while (TRUE) 
34
  {
35
       newsockfd = accept(sock, (struct sockaddr *) &cli_addr, &clilen);
36
       if (newsockfd < 0) 
37
          BailOut("ERROR on accept");
38
       
39
       while(TRUE)
40
       {
41
         bzero(recvbuf,2);
42
         n = read(newsockfd,recvbuf,255);
43
         if (n < 0) 
44
         {
45
           fprintf(stderr,"ERROR reading from socket");
46
           break;
47
         }
48
         
49
         printf("Here is the message: %d %d\n",recvbuf[0],recvbuf[1]);
50
         if(recvbuf[0]==0)  /* end condition */
51
           break;
52
         
53
         if(g_bigreceived==TRUE)  /* get size of package */
54
      {
55
        length=LENGTH_BIG_PACKET;
56
        g_bigreceived=FALSE;
57
      }
58
      else
59
        length=LENGTH_SMALL_PACKET;
60
         
61
         n = write(newsockfd,g_valid_message,length);
62
         if (n < 0) 
63
         {
64
           fprintf(stderr,"ERROR writing to socket");
65
           break;
66
         }
67
       }
68
     } /* end of while */
69
}

der java seitige teil
1
public class TcpConnection {  
2
  private int length = 0;
3
  
4
  private Socket socket = null;
5
  private PrintWriter out = null;
6
    private BufferedReader in = null;
7
  
8
  public TcpConnection(String host, int port)
9
  {    
10
    try {
11
      socket = new Socket();  
12
      socket.connect(new InetSocketAddress(host, port));
13
      
14
      out = new PrintWriter(socket.getOutputStream(), true);
15
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
16
      
17
      socket.setSoTimeout(2000);
18
      
19
    } catch (IOException e) {
20
      e.printStackTrace();
21
      System.err.println("Socket creating ERROR: " + e.getMessage());
22
    }
23
  }
24
  
25
  public short[] receiveData()
26
  {
27
    byte number = 0;
28
    short[] result = receiveData(number);
29
    
30
    return result;
31
  }
32
  
33
  public short[] receiveData(byte number)
34
  {
35
    char[] buffer = new char[210];
36
    
37
    try {
38
      //write welcome message
39
      out.println(number);
40
      
41
      //get response
42
      length = in.read(buffer);
43

44
    } catch (IOException e) {
45
      System.err.println("ERROR reading from TCP-Socket: " + e.getMessage());
46
    }
47
    
48
    short[] data = unsignedconverter(buffer);
49
       
50
      return data;
51
  }
52
  
53
  /**
54
   * returns the length of the current packet
55
   * @return
56
   */
57
  public int getLength()
58
  {  
59
    return length;
60
  }
61
  
62
  public void closeConnection()
63
  {
64
    if(socket != null)
65
    {
66
      try {
67
        socket.close();
68
      } catch (IOException e) {
69
        System.err.println("ERROR closing TCP-Socket: " + e.getMessage());
70
      }
71
    }
72
  }
73
  
74
    /**
75
     * Converts a char array into a unsinged short array
76
     * @param input
77
     * @return
78
     */
79
    private short[] unsignedconverter(char[] input)
80
    {
81
      short[] result = new short[input.length];
82

83
        int firstByte = 0;
84
    
85
        for(int i=0; i<input.length;i++)
86
        {
87
          firstByte = (0x000000FF & ((int)input[i]));
88
          result[i] = (short)firstByte;
89
        }
90
        
91
      
92
      return result;
93
    }

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 :)
#635408
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
#635596
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...
#637219
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
#637262
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

Eine eigene Frage? Dieser Thread ist über 19 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.