Solved

reading strings from a socket

Posted on 1999-01-18
4
218 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 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.

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

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…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

708 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now