4 Replies Latest reply: Oct 31, 2009 11:01 AM by 843790 RSS

    java client cpp server socket program

    843790
      hi guys im tryin to do a java client / c++ server socket program .in the java client program i serialize the object and pass them over socket to c++ server.now when im gettin them in c++,im not able to deserialize it properly as i tried for binary serialization since c++ does not support object serialization.but it didnt work out properly,as when im printin the member variables of c++ class im gettin junk values.i did came across many libraries like Boost which supports serialization but was not sure whether it will deserialize a java object.

      so what if my approach for dis problem is right or shud i go for JNI or any other concepts.if its in JNI then i fear my c++ server 'ill be loaded as shared library file along with java file at runtime which i think 'ill not be a right way to do client-server socket program.

      my java client code:
      import java.io.*;
      import java.net.*;
      
      public class KnockKnockClient
      {
           public static void main(String[] args) throws IOException
           {
                Socket kkSocket = null;
                ObjectOutputStream oos=null;
                Sample s;
                String str="hello dude";
           
                try{
                            kkSocket = new Socket("localhost", 4455);
                     oos = new ObjectOutputStream(kkSocket.getOutputStream());
                   }
                catch (UnknownHostException e)
                {
                            System.err.println("Don't know about host: 192.168.1.137.");
                            System.exit(1);
                   }
                catch (IOException e)
                {
                            System.err.println("Couldn't get I/O for the connection to: 192.168.1.137.");
                            System.exit(1);
                   }
                s=new Sample();
                
                oos.writeObject(str);
                
                System.out.println("name :" + s.name);
                      System.out.println("age  :" + s.value);
                      kkSocket.close();
          }
      }
      
      class Sample implements Serializable
      {
           String name="xyz";
           int value=10;
      }
      my c++ server code :
      #include <iostream> 
      #include <fstream>
      #include <string>
      #include<sys/types.h>
      #include<sys/socket.h>
      #include<netinet/in.h>
      #include<arpa/inet.h>
      #include<sys/stat.h>
      #include<fcntl.h>
      
      using namespace std;
      class Data
      {     
           public:
                char data1[255];
                char val1[255];
      };
           
      int main()
      {
             int create_socket,new_socket,fd;
             socklen_t addrlen;
             struct sockaddr_in address;
      
           if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)
               cout<<"The socket was created\n";
             address.sin_family = AF_INET;
             address.sin_addr.s_addr = INADDR_ANY;//INADDR_ANY;inet_addr("localhost");
             address.sin_port = htons(4455);
             cout<<"\nworking";
      
             if (bind(create_socket,(struct sockaddr *)&address,sizeof(address)) == 0)
               cout<<"Binding Socket\n";
      
             listen(create_socket,3);
             addrlen = sizeof(struct sockaddr_in);
      
           cout<<"*************************\n";
             new_socket = accept(create_socket,(struct sockaddr *)&address,&addrlen);
           cout<<"*************************\n";
      
      
           Data dobj;
           if (new_socket > 0)
           {
                     cout<<"The Client "<<inet_ntoa(address.sin_addr)<<" is Connected...\n";//inet_ntoa(address.sin_addr));
                int ch = recv(new_socket,&dobj,1023,0);
                perror("recv");
                cout<<"Status = "<< ch<<"\n";     
                ifstream in("binary.txt", ios::binary);
                in.read((char*)&dobj, sizeof(dobj));
      
                if(ch !=-1)
                {
                     cout<<"Client: received "<<dobj.data1<<"\n";
                     cout<<"Client: received "<<dobj.val1<<"\n";
                     cout<<"Request Completed\n";
                     
                }
                else
                perror("recv");
           }
           else
           {
                cout<<"Client not connected ...\n";
           }       
                close(new_socket);
                  return close(create_socket);
      
      }
      o/p for client / server looked like this:

      java client:
      *********************

      *********************

      name :xyz
      age :10

      c++ server:
      The socket was created

      workingBinding Socket
      *************************
      *************************
      The Client 127.0.0.1 is Connected...
      recv: Success
      Status = 4
      Client: received &#65533;
      Client: received _+
      Request Completed

      it would be great if any1 cud throw a light on this topic on how to deserialize a java object in c++ if its possible , if its not possible , then what all other concepts i can use to solve dis problem.

      thanx
        • 1. Re: java client cpp server socket program
          843790
          coder87 wrote:
          it would be great if any1 cud throw a light on this topic on how to deserialize a java object in c++ if its possible , if its not possible , then what all other concepts i can use to solve dis problem.
          It may be possible, but will likely be more work than it's worth. I would instead define some kind of message protocol and use a DataOutput/InputStream to communicate with your C++ app.
          • 2. Re: java client cpp server socket program
            EJP
            i serialize the object and pass them over socket to c++ server.
            You can't do that. Use a DataOutputStream and write the primitive data only, one field at a time. At the C++ side, read the data into indivual fields of each struct. The data will arrive in network byte order with no padding.
            • 3. Re: java client cpp server socket program
              843790
              ejp wrote:
              i serialize the object and pass them over socket to c++ server.
              You can't do that. Use a DataOutputStream and write the primitive data only, one field at a time. At the C++ side, read the data into indivual fields of each struct. The data will arrive in network byte order with no padding.
              hi endasil n ejp thanx for ur replies,

              if my class is containing more than 10-15 member variables n if im writing each of them individually then i think it's a tedious way to do so,n btw i posted a wrong O/P for java client as instead of writting :
              oos.writeObject(s);
              i wrote :
              oos.writeObject(str);
              im really sorry for tat. so my o/p of java client looked like this :

              java client:

              *********************

              *********************

              Exception in thread "main" java.net.SocketException: Broken pipe
              at java.net.SocketOutputStream.socketWrite0(Native Method)
              at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
              at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
              at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1855)
              at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1764)
              at java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1266)
              at java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1220)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1404)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1167)
              at java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1555)
              at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
              at KnockKnockClient.main(KnockKnockClient.java:36)

              c++ server:

              The socket was created

              workingBinding Socket
              *************************
              *************************
              The Client 127.0.0.1 is Connected...
              recv: Success
              Status = 4
              Client: received &#65533;
              Client: received _+
              Request Completed

              now in the above java client code,if im not serializing n if im using PrintWriter object alone i.e
              import java.io.*;
              import java.net.*;
              
              public class KnockKnockClient
              {
                   public static void main(String[] args) throws IOException
                   {
                        Socket kkSocket = null;
                           PrintWriter out = null;
                             Sample s; 
              try{
                             System.out.println("*********************\n");
                                    kkSocket = new Socket("localhost", 4455);
                             System.out.println("*********************\n");
                             out = new PrintWriter(kkSocket.getOutputStream(), true);
                        }
                        catch (UnknownHostException e)
                        {
                                    System.err.println("Don't know about host: 192.168.1.137.");
                                    System.exit(1);
                           }
                        catch (IOException e)
                        {
                                    System.err.println("Couldn't get I/O for the connection to: 192.168.1.137.");
                                    System.exit(1);
                           }
                        s=new Sample();
                        
                        System.out.println("name :" + s.name);
                              System.out.println("age  :" + s.value);
                        out.print(s);
                      out.close();
                      kkSocket.close();
                  }
              }
              
              class Sample 
              {
                   String name="xyz";
                   int value=10;
              }
              then O/P :

              c++ server:
              The socket was created

              workingBinding Socket
              *************************
              *************************
              The Client 127.0.0.1 is Connected...
              recv: Success
              Status = 13
              Client: received Sample@a97b0b&#65533;
              Client: received _+
              Request Completed

              now in the above code if im passing string obj instead of object of class Sample then fortunately itz printing the xact string value in c++ i.e
              String str="hello dude";
              out.print(str);
              c++:
              char buf[1024];
              int ch=recv(new_socket,&buf,1023,0);// here string object is received as char array
              cout<<"Client: received "<<buf;
              O/P:
              c++ server:

              The socket was created

              workingBinding Socket
              *************************
              *************************
              The Client 127.0.0.1 is Connected...
              recv: Success
              Status = 10
              Client: received hello dude

              so i cant understand if im able to pass n receive string obj successfully in c++ using printwriter without serialization in java n also s without deserialization in c++ ,then y im not able to pass/ receive objects f user defined class (for eg: "class Sample" in my code) in c++.

              is thr any way to pass objects at one go rather than passing all fields in a class individually which u suggested ??

              thanx
              • 4. Re: java client cpp server socket program
                843790
                coder87 wrote:
                so i cant understand if im able to pass n receive string obj successfully in c++ using printwriter without serialization in java n also s without deserialization in c++ ,then y im not able to pass/ receive objects f user defined class (for eg: "class Sample" in my code) in c++.
                You're not passing a String object. Your PrintWriter is behind-the-scenes turning your String into a set of bytes that C++ code can understand (using a character encoder).
                is thr any way to pass objects at one go rather than passing all fields in a class individually which u suggested ??
                Not really, just go do it. ObjectOutput/InputStream are completely wrong here; they're designed for two Java endpoints. That's not what you have.

                It's really not that hard, though, unless you have a very bad class design. Just add a
                void write(DataOutputStream stream);
                method to each class and handle writing that class out recursively. In other words, don't put all the logic to write an object graph into one method, delegate it to the classes to write themselves.