reading strings from a socket

Posted on 1999-01-18
Last Modified: 2010-04-02
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>
Question by:tblackwe
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2

Accepted Solution

Cov earned 100 total points
ID: 1184441
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.


Author Comment

ID: 1184442
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.

Author Comment

ID: 1184443
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.

Expert Comment

ID: 1184444
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.

Featured Post

[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

617 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question