sending udp packets in format osc (Open sound control) using pnet in Matlab R2012a - matlab

I have a question concerning udp packets in MATLAB. I've been using the oscsend.m script to send udp packets to other applications.
http://www.mathworks.fr/matlabcentral/fileexchange/31400-send-open-sound-control-osc-messages/content/oscsend.m
It works normaly. however, now I need to make use of the pnet function from the TCP/UDP/IP Toolbox 2.0.6 http://www.mathworks.de/matlabcentral/fileexchange/345-tcpudpip-toolbox-2-0-6
because I no longer have access to the instrument control toolbox in Matlab, which oscsend makes use of.
I looked up online for answers and even contacted the authors with no luck so far. Even though the problem seems trivial I couldn't make it work.
normally the usage with the Instrument Control toolbox would be:
u = udp('127.0.0.1', 12345) %12345 being the port
fopen(u)
oscsend(u, /test, 'f', 1.05) %"f" indicating a floating number
but now without udp or fopen I tried to use pnet like this
%write data to UDP
data = [oscstr(path) types data];
sock=pnet('udpsocket',12345) %it returns 0, a sign that the socket is working
%however when I try to send the oscsend signal through this socket nothing happens
pnet(sock, 'writepacket' data) %data being the output of oscsend
I also tried with no luck integrating the pnet function to oscsend but I couldn't recieve a signal, (I am working with another instance of MATLAB which is recieving the data sent from the previoulsy mentioned port).
This is what I did inside oscsend and none of them worked
%write data to UDP
data = [oscstr(path) types data];
%pnet(u, 'writepacket', data, '127.0.0.1', 12345 );%
%pnet u 'write' data %
%pnet(u,'write',data, '127.0.0.1', 12345 )
%pnet(u,'write',data, '127.0.0.1', 12345 ) %returned value?
%pnet(0,'write',data, '127.0.0.1', 12345 ) %
%sock = pnet('udpsocket',12345 ); %
%pnet(sock,'write', data, '127.0.0.1', 12345 )
Thanks to all of you in advance who took the time to read this.
Best.
Mario.

It's not clear to me what UDP port you want to send your data to, and what sort of process you're using to monitor and test your code. There are two ports involved... One is the local port that you're binding to (that's the argument to 'udpsocket'), and the other port is the destination port of the packet, given along with the destination host.
It appears to me that the Instrument Control Toolbox syntax requires the destination hostname and port during creation. It allows you to specify the local port as an optional argument if you want to. In constrast, pnet('udpsocket') takes the local port. You should notice in your first set of code that nothing specifies the destination host, which should make you suspicious... If you read on in the UDP docs of pnet.m, you'll see that there's another function: pnet(sock, 'udpconnect', 'hostname', port), which "connects" the UDP socket to the host/port pair, so that you can leave out the hostname/port when doing writepacket.
So here is what I think the equivalent is of your original Instrument Control Toolbox code:
sock=pnet('udpsocket',1237); % Does local port matter? You haven't said...
pnet(sock, 'udpconnect', '127.0.0.1', 12345); % Destination port
pnet(sock, 'writepacket', data);
You should ALWAYS use 'writepacket' for UDP, never 'write'. And note that you can either do 'udpconnect' as I've listed above, OR you can supply hostname/port with every writepacket, as you were trying to do.
What I can't figure out from your question is how 6351 enters in, as that never showed up in your reference code.

btw, there is also oscmex, a library based on liblo that allows you to send/receive OSC messages directly from/within matlab.

Thanks to my supervisor here is the code if you ever need to send udps via oscsend.m using pnet
http://www.mathworks.fr/matlabcentral/fileexchange/31400-send-open-sound-control-osc-messages/content/oscsend.m
just add the following code at the end of oscsend.m
%write data to UDP
data = [oscstr(path) types data];
pnet(u, 'write', data)
pnet(u, 'writepacket', '127.0.0.1', 12345); %127.0.0.1 being the IP and 12345 the port

Related

Accessing USB Port in Matlab/Psychtoolbox

I'm trying to access a buttonbox to record subject responses in matlab, but I can't access the usb port or the device attached. I've tried a lot of variations of the following code. what I currently have is:
port = serial ('COM2', 'BaudRate', 19200);
handle = CMUBox('Open', 'pst', port);
I keep getting all error messages either that I'm using the wrong argument type (referring to the 3rd arg 'port' in the second line) or that no such serial port device exists (again referring to 'port').
Any ideas?
The input to CMUbox should be the port name, like 'COM2', not a port object, like the variable port. See the
CMUBox docs for more details.
PS - Make sure that "COM2" is a correct port number. Often (not always) with Windows only COM3 and higher will be valid external devices.

Processing of a TCP packet

I am wondering what is happening between the creating a TCP packet and a [Ethernet[IP[TCP-packet]]] leaving the network adapter.
When i use for example a TCP program and want to send a single packet ( or could be more in fact TCP using byte streaming).
So i set up in any language a function called socket(...);
So my OS, refering to any documenation, creating me an interface with a specified port on which I can receive and send data over.
And if I create a TCP package (for example sendto(...), it will be send to the socket.
But what kind processes are done now [1], until my packet will leave the network adapter with an Ethernet + IP Header?
[1]: Where are the following steps happening (OS/Network adapter) and how does it exactly work?
Hope you understand me.. and please correct me if I missunderstood something wrong.

How to bind to any available port?

I need an app that sends an UDP packet to some network server and receives the response. The server replies to the same port number where request came from, so I first need to bind() my socket to any UDP port number.
Hardcoding the UDP port number is a bad idea, as it might be used by any other application running on the same PC.
Is there a way to bind an UDP socket to any port available? IMO it should be an effective way to quickly obtain a free port #, which is used by e.g. accept() function.
If no, then what's the best strategy to try binding and check for WSAEADDRINUSE/EADDRINUSE status: try the ports sequentially starting from from 1025, or 1025+rand(), or some other?
Another option is to specify port 0 to bind(). That will allow you to bind to a specific IP address (in case you have multiple installed) while still binding to a random port. If you need to know which port was picked, you can use getsockname() after the binding has been performed.
Call sendto without calling bind first, the socket will be bound automatically (to a free port).
I must be missing something, why don't you use the udp socket to send back data?
Start with sendto and then use recvfrom function to read incoming data also you get as a bonus the address from which the data was sent, right there for you to send a response back.

How do i get a free socket port? C++

I am writing a UDP test client/server and i want to get it through firewall. Supposedly all i need to do is have both sides send to the correct IP and server. Getting an IP is not a problem but how do i have the client pick a random free port and report it to the user? I eventually would want it to connect to a matchmaker server but right now i need a simple working prototype and i would like to cout the port number so my friend/tester can send me the # via IM so we can test.
How do i get the port number?
sorry for the long desc. I notice people tell me not to do what i am asking when i dont give a desc :(
To use the highly technical term, this is actually a pretty icky problem or even a pair of icky problems. Depending on the configuration of the firewall, it will usually allow responses from another endpoint on the IP endpoint as the request came from. So... if you friend receives the UDP datagram using something like the recvfrom() system call, the address parameter will receive the IP endpoint information to respond to. So the other end should be able to respond with a sendto() using the same addressing information. Something like:
/* initiator */
struct sockaddr_in hisaddr;
memset(&hisaddr, 0, sizeof(hisaddr));
hisaddr.sin_addr.s_addr = htonl(target_ip);
hisaddr.sin_port = htons(target_port);
sendto(sd, msg_ptr, msg_sz, 0, (struct sockaddr*)&hisaddr, sizeof(hisaddr));
/* receiver */
struct sockaddr_in peeraddr;
socklen_t peer_sz = sizeof(peeraddr);
recvfrom(sd, buf_ptr, buf_sz, 0, (struct sockaddr*)&peeraddr, &peer_sz);
/* build response */
sendto(sd, msg_ptr, msg_sz, 0, (struct sockaddr*)&peeraddr, peer_sz);
The peeraddr on the other side will be your external address or, more correctly, the IP address of your firewall and the port number that it chose to use. The port number that you specify in your code may be completely different than the port that your friend would have to send data to. Ultimately, it might not matter what port you choose to use since the firewall might be sending and receiving on an entirely different port - this is what Network Address Translation is all about. I would recommend reading RFC3235 for some tips on how to overcome that hurdle.
The best approach IMHO is to:
Let the OS choose a port by either calling bind() with a zero port number or skipping the bind altogether
Having the client receive the address information from the socket layer (e.g., the fifth and sixth arguments to recvfrom())
The client sends response to the endpoint retrieved in the previous step
Tweak the firewall configurations until the previous steps work
Of course, all of the magic is in the last step. If you can disable NAT or ensure that the firewall is never going to switch ports, then nailing down a port number and bind-ing to it will work as well. You might want to take a look at %WINDIR%\system32\drivers\etc\services (or /etc/services depending on your OS inclination) to get an idea of what port numbers are reserved or generally in use.
bind() the socket before you send your data. Specify port 0 to bind(), and the OS will pick an unused port for you. You can then use getsockname() to find out what port wsa chosen.
Generally speaking - you - as the developer - choose the port. You can set your application to read the port from a config file or user input - but no magic firewall is going to tell you what port to use...
If I'm understanding your question correctly, I'm not sure there's a way to do what you want programatically (and even if there is, I don't think it's the right approach). I think you need to find a port that isn't in use on the server machine (and perhaps a different or the same port on the client machine, if communication is bi-directional) AND that port must be able to pass through your firewall. I assume since you say "getting an IP is not a problem", you've already configured your firewall to forward some or all ports to a specific computer inside the firewall? If so, the port you seek is one of the ones you forwarded. You can just pick an arbitrary one, as long as no other service is running on that port. Ports below 1024 are reserved, so you probably want to pick a higher number than that. You can use a simple portscanning tool such as nmap to see which services are running on your computer on which ports and pick a different one. Note that nmap can be fooled by firewalls and various bind rules when sockets are created.
I think you're better off picking a fixed port rather than relying on the random port number chosen by the O/S.
If you use a random port you'd have to change your firewall settings each and every time you run the program.
If you're using WINSOCK check this link:
http://msdn.microsoft.com/en-us/library/aa280717(VS.60).aspx
Basically you have 2 choices set the port to 0 and let the system assign you one or chose a random one try to open the socket if it doesn't work try another (be sure to steer clear of reserved ports)

BroadCasting

Ok in order to broadcast, I have created a socket:
notifySock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
And to send the hostname of my computer to all other computers connected to the same lan, I am using the send(Byte[] buffer) method:
notifySock.Send(hostBuffer);
hostBuffer contains the hostname of my computer.
However because I am using a 'datagram' socket-type do I need to format the data I need to send.
If possible please provide the code that I must put in between the two lines of code I have entered to create a socket and send the data.
For broadcast from a user application, UDP is typically used. You need to design a suitable protocol, i.e. a way to format the information you want to send into the UDP packet.
In your example you haven't specified who you are sending to. You need something like:
UdpClient notifySock = new UdpClient(endPoint);
notifySock.Send(buffer, buffer.Length, new IPEndPoint(IPAddress.Broadcast, 1234));
For the other hosts on your LAN to receive that they have to be listening on UDP port 1234.