3

I am trying to send some string from A Java client to a C server using C. First I send the length of the String. Then, I allocate the memory manually in C and finally I send the String character by character.

The problem that sometimes I get the right String and some times I get the whole String + Extra other unknown Character (like I am allocating more than I get).

Here is the Java Code:

protected void send(String data){
    short dataLength=(short)data.length();
    try {
        out.write(dataLength);
    for (int i=0; i<data.getBytes().length ;i++)
    {
        out.write(data.getBytes()[i]);
    }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }       
}

And here is the C code :

void read4(int sock, int *data)
{

    char dataRecv;
    char* memoireAllouee=NULL;
    int stringLength;
    int i=0;
    recv(sock, (char*)&dataRecv, sizeof(dataRecv), 0) ;
    *data = dataRecv;
    stringLength=dataRecv;
    memoireAllouee=malloc(sizeof(char)*stringLength);
    if (memoireAllouee==NULL)
    {
        exit(0);
    }
    for (i=0;i<stringLength;i++)
    {
        recv(sock, (char*)&dataRecv, sizeof(dataRecv), 0) ;
        *data = dataRecv;
        memoireAllouee[i]=dataRecv;
    }
    printf("\n\n%d\n\n\n",stringLength);
    printf("\n%s\n",memoireAllouee);
}

If you think also that this method is not optimal can you help me with a faster one?

3
  • @trutheality: If you copy-and-paste the involved line on each routine into an answer, that would make a pretty excellent answer. Commented Apr 23, 2012 at 0:13
  • 1
    @sarnold I took a look in the docs and it looks like out is probably a DataOutputStream, and if so, the matching method is write( int ) which writes the bottom 8 bits of the int to the stream. That explains why the length is being transmitted correctly (or close to it, it would have been much worse if it were really sending the short). It also means that the conversion to short is either completely unnecessary, or an attempt to save 16 bits of space in the temporary variable storing the length. Commented Apr 23, 2012 at 5:19
  • @truthreality: Your answer is the wright one !.. I was very stupid, I didn't pay attention for the char in the C side. So this what happens : When I send a String <127 char Every thing is OK and when I send a String >127 char many random cases happens... (writing the String and other strange charachter, not writing the string at all,...) Thank you Again. Ah just another thing, For information (for others). I have converted the short to an array of 2 bytes an just send it. Commented Apr 23, 2012 at 14:10

2 Answers 2

9
protected void send(String data){
    short dataLength=(short)data.length();
    try {
        out.write(dataLength);
    for (int i=0; i<data.getBytes().length ;i++)
    {
        out.write(data.getBytes()[i]);
    }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }       
}

For starters, you're recomputing the entire getBytes() array twice for every character. Save the byte[] to a variable byteArray and use that -- you're making this take quadratic time, completely unnecessarily. Additionally, why not just call out.write(byteArray) directly, instead of doing the for loop?

Secondly, data.length() isn't always equal to data.getBytes().length(). Make sure you're writing byteArray.length instead of just data.length().

Finally, make sure you're using a consistent charset on both ends. The string-to-byte-array mapping is heavily dependent on the Charset, so be sure it's the same Charset on both sides so you don't run into encoding issues.

Sign up to request clarification or add additional context in comments.

Comments

4

To answer your second question:

for (int i=0; i<data.getBytes().length ;i++)
{
    out.write(data.getBytes()[i]);
}

should be just:

out.write(data.getBytes());

and

for (i=0;i<stringLength;i++)
{
    recv(sock, (char*)&dataRecv, sizeof(dataRecv), 0) ;
    *data = dataRecv;
    memoireAllouee[i]=dataRecv;
}

should be:

int offset= 0;
while (offset < stringLength)
{
    int count = recv(sock, &memoireAllouee[offset], stringLength-offset 0) ;
    if (count == 0)
        // premature EOS .. do something
        break;
    if (count == -1)
        // Error ... do something
        break;
    offset += count;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.