reading strings from a socket

I have a java program that is writing to a socket(5 ints and 2 strings).  My c++ server program is using the "readn" function to read the values from that same socket into a buffer.  I'm then casting that buffer to a structure consisting of 5 ints and two char[]'s.  I'm getting all of the values from the socket fine except for the last string.  It seems that the remaining bytes in the buffer are being captured by the first char[] and nothing is being captured by the second char[].  Even if I allocate the exact number of characters I'm expecting from my java program in my structure (example char signString[41] and char wavSrc[15) it still is putting all the remaining bytes in the first char* when reading in the buffer in the C++ code.  Any suggestions?  I'll send my code if it willl make things clearer>
Who is Participating?
CovConnect With a Mentor Commented:
Hmmm...maybe for some reason java is sending some kind of junk at the end of the string... try just adding a junk variable to the end of you data structure (5 ints, 2 strings, 1 int junk), and that way the junk var will get the junk, and your strings will be okay.

tblackweAuthor Commented:
Here's my java code:

      public void sendRecordMsgCommand(int harId, int msgId, int numSigns, String signString, String wavSrc) throws IOException
            int stringBytes = 0;
            int stringArrayBytes = 0;
            int totalBytes = 0;

        if (clientId == UNASSIGNED_CLIENT_ID)
                  System.out.println("right before throw");
            throw (new IOException("Cannot send record message command.\nConnection with the HAR Router\nhas not yet been confirmed."));
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bo);
        if (wavSrc != null)
                  stringBytes = wavSrc.length();      // each char in the string is 1 byte
            if (selectedSigns.length != 0)
                  for (int i = 0; i < selectedSigns.length; i++)
                        stringArrayBytes = selectedSigns[i].length();
                        totalBytes+= stringArrayBytes;
            totalBytes = signString.length();
                  System.out.println("stringBytes is " + stringBytes);
                  System.out.println("wavSrc is " + wavSrc);
                  dos.writeInt(0);                  // device id
                  dos.writeInt(0);                  // ??
                  dos.writeInt(RECORD_MSG);      // from HAR_CMD enum
                  dos.writeInt(clientId);            // saved from connection response
                  dos.writeInt(0);                  // router_id ?? not sure if correct value yet
                  System.out.println("totalBytes is: " + totalBytes);
                  dos.writeInt(totalBytes + stringBytes + 16);      // number of bytes in data_area[] (4 ints @ 4 bytes)
                  dos.writeInt(harId);            // data_area(harId)
                  dos.writeInt(msgId);            // data_area(id of the message to record)
                  dos.writeInt(totalBytes);      // data_area(number of bytes in 'signString')
                  dos.writeInt(stringBytes);   // data_area(number of bytes in 'wavSrc)
                  //System.out.println("selectedSigns.length is: " + selectedSigns.length);
                  //dos.writeInt(selectedSigns.length);            // data_area(number of signs to flash)
                  for (int j = 0; j < selectedSigns.length; j++)
                  if (totalBytes > 0)
                        System.out.println("signString is: " + signString);
                        dos.writeBytes(signString);      // data_area(name of signs in the sign list)
                  if (stringBytes > 0)
                        System.out.println("wavsrc is: " + wavSrc);
                        dos.writeBytes(wavSrc);            // date_area(name of the .wav file)
            catch(IOException ioe)
                  throw new IOException(ioe.getMessage());
            bo = null;
            dos = null;

here's my c++ code:

struct recordMsgData
      java_int harId;
      java_int msgId;
      java_int signStringLen;
      java_int wavFileLen;
      java_int numSigns;
      java_char signString[56];
      java_char wavSrc[15];

recordMsgData *recordHarData;
static MsgBuf cmd_data(cmd_data_len);        // client <--> server data area

int i;
      int harId;                        // har Id
      int      msgId;                                      // message Id
      int wavFileLen;                                // size of the wav file being passed
      int signStringLen;                          // size of the sign string being passed
      char *wavSrcFile;                          // name of the wav file to be recorded
      char *signList;                                 // id of signs to flash for a broadcasted message
      char *selectedSigns[MAX_SIGNS];        // id of signs to flash for a broadcasted message
      int numSigns;                                // number of signs in the sign list

if (int x = readn(fd, cmd_data.buf, data_size, data_timeout) != data_size)
            std::cout << "Error reading in cmd_data.  x = " << x << endl;
            log_error(__FILE__, __LINE__, SEVERE, COMMUNICATION_MSG,
              -1, false, true,
              "Error in reading cmd data");
        //return HAR_ERROR;

recordHarData = (recordMsgData*)cmd_data.buf;
                  harId = ntohl(recordHarData->harId);
                  std::cout << "harId = " << harId << endl;
                  msgId = ntohl(recordHarData->msgId);
                  std::cout << "msgId = " << msgId << endl;
                  signStringLen = ntohl(recordHarData->signStringLen);
                  std::cout << "signStringLen = " << signStringLen << endl;
                  wavFileLen = ntohl(recordHarData->wavFileLen);
                  std::cout << "wavFileLen = " << wavFileLen << endl;
                  recordHarData->signString[signStringLen + 16] = '\0';
                  signList = recordHarData->signString;
                  std::cout << "signString = " << signList << endl;
                  recordHarData->wavSrc[wavFileLen] = '\0';
                  wavSrcFile = recordHarData->wavSrc;
                  std::cout << "wavSrcFile = " << wavSrcFile << endl;
                  numSigns = ntohl(recordHarData->numSigns);
                  std::cout << "numSigns = " << numSigns << endl;
                  sizeOfData = ntohl(msg.data_size);
                  std::cout << "sizeOfData = " << sizeOfData << endl;

my problem is that "wavSrcFile" is not receiving any data.  "signString is receiving all of the bytes.
tblackweAuthor Commented:
I moved the integer "numSigns" to be the last item written to and read from the stream, after the strings, and it my c++ code is not getting any value.
Hmmm....  Perhaps the datatype for char is two bytes on the server side... so you get one byte for each char sent, and the server reads two bytes for each char... try reading the character in as first short integers, then type casting them as integers.  That may work.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.