Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

reading strings from a socket

Posted on 1999-01-18
4
Medium Priority
?
227 Views
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>
0
Comment
Question by:tblackwe
  • 2
  • 2
4 Comments
 
LVL 1

Accepted Solution

by:
Cov earned 200 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.

0
 

Author Comment

by:tblackwe
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();
        try
        {
                  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)
                  dos.writeInt(numSigns);
                  
                  /*
                  for (int j = 0; j < selectedSigns.length; j++)
                  {
                        System.out.println(selectedSigns[j]);
                        dos.writeBytes(selectedSigns[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)
                  }
                  send(bo);                              
            }
            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");
            shutdown_router_sock();
            //return;
        //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.
0
 

Author Comment

by:tblackwe
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.
0
 
LVL 1

Expert Comment

by:Cov
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.
Cov
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

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

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
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 be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

886 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