Why did parseFrom() function hang using protobuf in java socket? - java

I just want to create echo server/client using protobuf and java.
I tested with protobuf-java-2.4.1 and jdk1.7.
I wrote echo server code like below
// create server socket and accept for client connection.
// ...
link = servSock.accept();
Person person = Person.parseFrom(link.getInputStream()); // blocking position
person.writeTo(link.getOutputStream());
I think it is not necessary to note Person.proto.
The client code is only send Person object using socket input stream and receive echo Person object.
// socket connect code was omitted.
Person person = Person.newBuilder().setId(1).setName("zotiger").build();
person.writeTo(echoSocket.getOutputStream());
person = Person.parseFrom(echoSocket.getInputStream());
But server was blocked in parseFrom function when the server and client both run.
I found if i use writeDelimitedTo() and parseDelimitedFrom(), then that is ok. I don't understand why the writeTo() and parseFrom() function does not working.
Why did the server blocking in there?
Is it necessary to send some end signal from client side?

The reason you have to use writeDelimitedTo()/parseDelimitedFrom() is that otherwise protocol buffers may have no idea how much data it needs to read from the socket. That presents a problem (I say may because you could of course create a message with only fixed length fields that wouldn't require this ... but protocol buffers has to deal with both cases)
The writeDelimitedTo() method writes the length of the message to the OutputStream then the message itself. Its counterpart parseDelimitedFrom() reads the length, then the message.
You can use writeTo() and pasrseFrom() with streams but only if you want to write/read a single message and are closing the stream after writing. The reader will then get an EOF to indicate the end of the message (also the case when reading from a file that contains only a single message).

Don't write your own Client/Server, ie. RPC solution. There is one here......https://code.google.com/p/protobuf-rpc-pro/ which has some nice features already for java.

Related

How can I make a server push

I developed my own client and server in java und I implemented a long-polling communication. So my client will always ask for new operations to be executed. If a server has a new operation, then he will send it to the client. The whole communication is based on java-sockets. Now I am thinking to renounce on long-polling-communication and implement a server-push. In this case the client will not ask my server anymore. He will just wait for notifications. If my server has a new operation to be executed, then he will make a server-push. My Goal is to save time on the client-side. So he will not send any request anymore
Question1: is it possible to implement a server-push on my model based on sockets in Java ?
Question2: if yes,how can I implement a server-push?
On server side:
...
DataOutputStream toClient = new DataOutputStream(socket.getOutputStream());
outToClient.writeBytes("event_xyz");
...
On client side you should listen for events
If I understood your question in the right way, you just have to wait for incoming data on the client. For example with a DataInputStream.readUTF(); this method waits until the ServerSocket pushes some data through the stream with the method DataOutputStream.writeUTF(String s) .

Listening to a multicast UDP address

I wrote an application in MATLAB to open a UDP socket and listen for incoming datagrams. Basically, something like this:
u = udp(rHost, rPort, 'LocalHost', lHost, 'LocalPort', lPort);
u.DatagramAvailableFcn = #(o,e) operateOnData(o,e);
fopen(u);
This works wonderfully when I'm listening to something in a unicast fashion. But I would now like to be able to listen to multicast traffic. Apparently, this isn't possible in MATLAB.
The workaround is, per above link,
As a workaround to connect to a UDP multicast, you can do the following:
Use a Java multicast socket to access it directly from MATLAB. For more information, see javadoc or tutorials for the "core java.net" classes from Sun, specifically "java.net.MulticastSocket". This could be found at:
http://java.sun.com/j2se/1.4.2/docs/api/java/net/MulticastSocket.html
I have no background in Java so this is a struggle for me. I've only been able to run the following to instantiate a MulticastSocket object:
>> ms = javaObject('java.net.MulticastSocket');
I looked around and found that I also need a java.net.Datagram object to actually contain the incoming stream.
How do I use the MulticastSocket and Datagram objects within the context of MATLAB? I'm trying to replicate the functionality of u.DatagramAvailableFcn, i.e., fire a callback to operate on the contents of the datagram once I receive one.
EDIT: Looks like this is how I want to go about this in terms of the Java, but now it's getting this back into MATLAB-land...
I successfully subscribed and received a packet from a multicast stream, by the following:
socket = java.net.MultiSocket(streamPort);
socket.joinGroup(java.net.InetAddress.getByName(streamIP));
socket.setReuseAddress(1);
packet = java.net.DatagramPacket(zeros(1, intmax('uint16'), 'int8'), intmax('uint16'));
socket.receive(packet);
socket.leaveGroup(InetAddress.getByName(streamIP));
socket.close;
msg = packet.getData;
msg = msg(1:packet.getLength);
This was essentially lifted from judp availble on the MathWorks File Exchange.
I am still looking for a way to get some equivalent of a DatagramReceivedFcn - right now it looks like the socket.receive call is blocking until it times out. I can use timer objects to fire the "callback" on a regular basis but that's of course not the same as having a DatagramReceivedFcn.

Is there any way possible to extract data after writing to outputstream?

I am trying to create several sockets and connecting it with a single client using socket programming. Every time a client tries to communicate with server a new socket gets created and messages can be sent but the problem comes when i try to pass more than one message through server. the first message gets sent and the for the rest, i face stream corrupted exceptions.Following is my code for the class that tries to read object from output stream.

Network output from server can't be read by client

So, I have a simple socket server and a socket. I run the socket server, successfully. The client socket connects and sends a string - this works. I want the server to write back different information based on this string. I can check what the string is and get an OutputStream to the client, but whenever I write to it and flush, the InputStream client-side is NEVER in a ready state, and will never get a message back... I just don't see what I'm doing wrong.
All the code is at http://pastebin.com/u/omegazero
NetworkAgent.java is the client, SimbadAgent.java is the server, and UserAgent.java is the actual implementation of said server (the server is abstract for other reasons).
Compile everything, then run UserAgent followed by NetworkAgent and you will see what happens.
Executed your code (after commenting the reference to StringQueue in SimbadAgent) and I got the following output.
wrote get_cmd
Input shutdown? false
iS()iI()iM()iB()iA()iD()i ()iB()iO()iO()iY()iA()NETWORKAGENT: Response to "get_cmd": "SIMBAD BOOYA"

to read the packet of bytes on client(client Socket) from server(ServerSocket) using java

i m a new .
i m a java developer(fresher) and currently i m working on BSE project and i m facing problem to read the packet of bytes on the client(client socket) from the server(server socket). if u can help me then please help me.
Thanks in advance
Well, if you want to interact directly with packets, then you need to use a DatagramSocket instead of the regular Socket and ServerSocket.
Then, you should visit this link to see a good tutorial on how to get started with sending and receiving individual packets.
The basic idea is that the Client or Server will block on the recieve() call while it waits for its partner to send a packet using send().
If you aren't interested in the individual packets like you indicated in your question, then you will want to use Socket and ServerSocket. The first step to communicating between the two involves code that will look similar to the following:
//Server
// this call will block until the client tries to connect to the server
Socket cientConn = new ServerSocket(8878).accept();
// now you can use the connection's input and output streams to send data
/******************/
// Client
Socket serverConn = new Socket(addressOfServer, 8878);
// now you can use the connections input and output streams
After you get connections set up, you will have basically 2 read/write loops. One on the client, and one on the server.
while(true) [
// check for data from an input stream
...
// respond with message back
}
You will need a similar loop for the client and the server.

Categories