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.
Related
I have read the Q&A's about broadcasting and I got the general idea. However, when playing with my Java code, I am confused.
My IP address is 192.168.8.102. When I broadcast to 192.168.8.255, I can receive the package that from myself and have it captured on wireshark. But when I broadcast to 255.255.255.255, the wireshark seems missing it though my code still receives it. When I run someone else's app, the wireshark captures the package that it broadcasts to 255.255.255.255.
Any explainations? Much appreciated!
PS. here is part of my Java code:
DatagramSocket senderSocket = new DatagramSocket(null);
senderSocket.setReuseAddress(true);
senderSocket.setBroadcast(true);
senderSocket.bind(new InetSocketAddress(2000));
InetAddress address = InetAddress.getByName("255.255.255.255");
byte[] SendBuffer = contentSent.getBytes();
senderPacket = new DatagramPacket(SendBuffer, SendBuffer.length, address, 2000);
senderSocket.send(senderPacket);
If your socket is not bound to a specific interface, packets send to 255.255.255.255 will be sent out on the default interface. If that's not the one Wireshark is listening on, that explains why it doesn't see it but your code does.
If your socket is bound to a specific interface, that guarantees that sending on that socket goes out on that interface.
As EJP mentioned in the comments, broadcasting to 255.255.255.255 is not recommended, in part because of the limitation I mentioned. You're better off using the broadcast address for the link in question, i.e. 192.168.8.255 in your case.
I'm implementing a FTP program using UDP in Java (TCP is not an option), but I'm having trouble grasping the basics of how it's supposed to work.
As I understand, it's connectionless, so I should just have one server thread running which processes every request by any client.
Where I'm getting confused is during the actual file transfer. If the server is in the middle of a loop sending datagrams containing bits of a requested file to the client, and is waiting for an ACK from the client, but instead of that receives a completely different request from a different client, how am I supposed to handle that?
I know I could jump out of the loop to handle it, but then if the initial expected packet finally arrives, how can I pick up where I left off?
A UDP server works similar to a TCP in many respects. The major difference is that you will not receive a acknowledgement that your packets were received. You still have to know which client you are sending to, so use the DatagramSocket class. This is the Oracle tutorial for UDP: http://docs.oracle.com/javase/tutorial/networking/datagrams/index.html. It has a pretty good example in it. The significant part is getting the address and port of the original client, and returning your packets to that client:
InetAddress address = packet.getAddress();
int port = packet.getPort();
new DatagramPacket(buf, buf.length, address, port);
You could start a new thread on the server side for sending the bits every time a client sends a request. The thread would save the return address and port of the client, and die when the file send was done.
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.
Looking to make a Java stop-and-wait UDP server and client but I'm running into some problems starting off. I've made a simple UDP client and server without the stop-and-wait part, but I would now like to learn how to change it. How can I send ACKs and implement timeouts using java sockets ?
Could someone please post up some examples for me to use in my implementation ?
If you're implementing this in UDP, sending and receiving acknowledgements is up to you. This seems to be what you want for this stop and wait protocol. In terms of pseudocode, you would want something like:
int Send(msg)
{
char rcvBuf[];
sentBytes = sock.send(msg);
sock.rcv(rcvBuf);
return sentBytes;
}
int Recv(rcvBuf)
{
String ackMsg = "ACK";
length = sock.rcv(rcvBuf);
sock.send(ackMsg);
return length;
}
After every send, you wait for an acknowledgement message to come in, and every time you receive, you send an acknowledgement.
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.