Recover port from Boost Asio udp::endpoint - networking

I am programming a server and client program to communicate between a windows PC using the Boost libraries and a Linux ARM beagleboard using the asio stand alone libraries. I have for a while had successful UDP communication between the two devices but now I want to recover the port from the endpoint the server discovers when the client connects. The way the client connects is via query:
udp::resolver resolver(io_service);
udp::resolver::query query_tx(udp::v4(), hostIP, "43210");
udp::endpoint receiver_endpoint_tx = *resolver.resolve(query_tx);
where host IP is a string and this works fine. Upon debugging though I notice that when i check the value returned by:
receiver_endpoint_tx.port()
This returns 51880. Now don't jump the guns and yell out network byte order and host byte order. I AM AWARE. The strange part is that this number 51880 sometimes is a different number and when i check what the server has stored in its endpoint it is a completely different number: 21743. Now I know I must be doing something wrong with the byte orders but i tried:
//unsigned long port_long = boost::asio::detail::socket_ops::host_to_network_long(receiver_endpoint_tx.port());
//unsigned long port_short = boost::asio::detail::socket_ops::host_to_network_short(receiver_endpoint_tx.port());
And they do not give me back my original port: 43210. Neither does network to host. So what am i missing and how can I on both ends recover my 43210 port? Obviously it must be there somewhere because they are successfully communicating.
Thanks in advance, sorry if noob mistake :)

Fistly, UDP is connectionless, there is no connection.
I'm not sure if I understand you correctly, but it sound too me like you want to bind to specific port numbers. If you want the client to send a packet from port x to port y on the server, and the server should respond from port y to port x, then you need to bind the sockets to the desired ports. Alternatively you can use the constructor to bind. Not doing so will result in the OS using ephemeral ports.
Further, to get the remote endpoint that a packet was received from the async_receive_from takes the sender_endpoint reference parameter. When the read handler is called, you can retrieve host and port from it.

Related

Confused between ports and sockets

Ok so when I tried to do research on ip addresses, ports, and sockets, this is what I got out of it:
IP Addresses are used to map to different devices over a network.
Port numbers are used to get to the specific application on the hosts.
Sockets are a combination of the two..
What I don't understand is that if ports connect you to a specific application, you should only have 1 port number per application right? But for example port 80 is used for HTTP, so if an application is using that port it's listening to HTTP requests right? So what happens if more than one person tries to access it? Sockets and ports have me confused a lot..
A socket is an abstraction used in software to make it easier for programmers to send and receive data through networks. They are an interface, which you use in application-level code, to access the underlying network protocol implementations provided by your OS and language runtime.
The TCP protocol, IP protocol, and other popular network protocols do not, in of themselves, have any concept of "sockets". "Sockets" are a concept which implementers of TCP/IP came up with.
So what is the concept of a "socket"? Basically, an object which you can write data to, and read data from. "Opening" a socket means creating one of those objects in your program's memory. You can also "close" a socket, which means freeing any system resources which that object uses behind the scenes.
Some kinds of sockets can be "bound" to local and remote addresses, which you can think of as setting some data fields, or properties, on the socket object. The value of those fields affect what happens when you read from or write to the socket.
In Unix, there are various kinds of sockets. If you "open" a TCP socket, "bind" it to local and remote addresses (and ports), and write some data into it, your libraries/OS will package that data up into a TCP segment and send it out through whichever network interface matches the local address which you "bound" the socket to. If you "open" an IP socket, and write some data to it, that data will be packaged up into a IP packet (without any added TCP headers) and sent out. If you open a "raw", link-level socket, and write to it, the data will be sent out as the payload of a link-level frame, minus IP and TCP headers. There are also "Unix domain sockets". If you open one of those and write to it, the data will be passed directly through system memory to another process on the same machine.
So although they are often used in non-OO languages like C, sockets are a perfect example of what OO languages call "polymorphism". If you ever have trouble explaining what "polymorphism" is to someone, just teach them about network sockets.
"Ports" are a completely different concept. The idea of "ports" is built in to TCP and other transport protocols.
Others may give more high-falutin', and perhaps more technically accurate, definitions of a "port". Here is one which is totally down to earth:
A "port" is a number which appears in the TCP headers on a TCP segment. (Or the UDP headers on a UDP segment.)
Just a number. Nothing more, nothing less.
If you are using a "socket"-based interface to do network programming, the significance of that number is that each of your TCP or UDP sockets has a "local port" property, and a "remote port" property. As I said before, setting those properties is called "binding".
If your socket's "local port" property is "bound" to 80, then all the TCP segments you send out will have "80" in the "sender port" header. Then, when others respond to your messages, they will put "80" in their "destination port" headers.
More than that, if your socket is "bound" to local port 80, then when data arrives from elsewhere, addressed to your port 80, the OS will pass it to your application process and not any other. Then, when you try to read from the socket, that data will be returned.
Obviously, the OS needs to know what port each of your sockets is bound to. So when "binding", system calls must be made. If your program is not running with sufficient privileges, the OS may refuse to let you bind to a certain port. Then, depending on the language you are using, your networking library will throw an exception, or return an error code.
Sometimes the OS may refuse to let you bind to a certain port, not because you don't have the right privileges, but because another process has already bound to it. However, and this is what some of the other answers get wrong, if certain flags are set when opening a socket, your OS may allow more than one socket to be bound to the same local address and port.
You still don't know what "listening" and "connected" sockets are. But once you understand the above, that will just be a small jump.
The above explains the difference between what we today call a "socket" and what we call a "port". What may still not be clear is: why do we need to make that distinction?
You have really got me thinking here (thank you)! Could we call the software abstraction which is called a "socket" a "port" instead, so that instead of calling socket_recv you would call port_recv?
If you are only interested in TCP and UDP, maybe that would work. Remember, the "socket" abstraction is not only for TCP and UDP. It is also for other network protocols, as well as for inter-process communication on the same machine.
Then again, a TCP socket does not only map to a port. A "connected" TCP socket maps to a local IP address, local port, remote address, and remote port. It also has other associated data, including various flags, send and receive buffers, sequence numbers for the incoming/outgoing data streams, and various other variables used for congestion control (rate limiting), etc. That data does not belong just to a local port.
There can be thousands of TCP connections going simultaneously through the same "port". Each of those connections has its own associated data, and the software object which encapsulates that per-connection data is a "TCP socket".
Even if you only use TCP/UDP, and even if you only have a single process using any given local port at one time, and even if you only have a single connection going through each local port at one time, I think the "socket" abstraction still makes sense. If we just called sockets "ports", there would be more meanings conflated in that one word. Reusing the same word for too many meanings hinders communication.
"Ports" are transport-protocol level identifiers for an application process. "Sockets" are the objects used in software to send/receive messages which are addressed from/to those identifiers.
Differentiating between "my address" and "the thing which sends letters addressed as coming from me" is a useful distinction to make. "My address" is just a label. A label is not something active, which does things like sending data. It is logical to give "the thing which is used to send data" its own name, different from the name which denotes "the sender address which the data is labelled with".
When application (say web server like Apache or Nginx) is listening on say port 80, it creates so called listening socket.
When some client comes, this listening socket gets update (which can be noticed via select or poll API), and our application creates communication socket. This socket is uniquely identified by tuple (src_addr, src_port, dst_addr, dst_port) - it is very much possible that many clients will have exact same (dst_addr, dst_port) combination.
Then our web server can talk over that communication socket to deliver say web page and eventually close this socket. When many clients come in parallel, web server can either create thread/process per client (Apache model), or service all sockets one by one (Nginx model).
Note that in this situation only one listening socket per port can exist - multiple application cannot bind to the same port like 80. But, it is perfectly ok to have many communication sockets (some people report successfully serving more than a million simultaneous requests).
Every time you accept a connection on a socket in listening state (e.g. on port 80), you will get a new socket in established state that represents a connection.
On the client side, each time a new connection (new socket that is being connected) is being made with that address and port, the operating system will assign a random port on your side.
For example if you connect two times:
your-host:22482 <---> remote-host:80
your-host:23366 <---> remote-host:80

Configure Wifly module to receive UDP packets

I have an RN-171 wifly module connected with a micro-controller.
I am using the UDP-protocol to communicate with the module. Also, I am using the firmware's UDP auto-pair feature to set the host ip. As soon as the module receives a UDP packet, it sets the host IP address to the ip from where it received the data. Now, this host ip cannot be changed without entering into the command mode.
I want the module to behave in the following way:
Every time it receives a UDP packet, it updates the host ip to the ip address from where that signal came from.
Also, I can use the TCP protocol but it only allows a single connection at a time. One more problem that I faced using the TCP protocol was that if I try to initiate a second TCP connection with the module, it not only refuses the second connection but also hangs the first stable connection. Even if the second connection initiation does not hang the module and it just gets refused, I will be ready to work with TCP.
I have been researching a lot on the web regarding this problem but since these modules are not widely used, they have a very limited support.
I've used RN-171 extensively and have many resolved tickets in their support system.
According to the WiFly Command Reference, Advanced Features and Applications User’s Guide, you cannot open more than one TCP port with the module. (the default number being 2000)
Unfortunately, regarding the UDP functionality, there's not much you can do. If you have a new host wishing to communicate over UDP, connect to the module over TCP, go into command mode and set the address using "$$$", "set ip host 0.0.0.0", "save", "exit" commands. Alternatively, instead of 0.0.0.0, you can enter the new host's own ip address: "$$$", "set ip host ###.###.###.###", "exit". Replace "###.###.###.###" with the ip address of the device.
This way, you won't get wrong host ip in case more than one device communicates over UDP at the same time. Also, by not using "save", the auto-pairing will still be saved to EEPROM memory. Also, you can send "ip flags 0x##" before "exit", this way you can also set bit[6] to 0 (UDP auto pairing disabled) temporarily by using the hex value that has this bit set to zero.
One of my problems that Microchip technical support tested around the summer of 2013 is that you cannot use RN-171 as an access point for other RN-171s since they have a firmware error preventing one from doing that and, as of firmware v4.41, released in January of 2014, there is no fix yet nor planned.
I myself do not recommend the latest firmware version v4.41, since it does not appear to work with most routers; however Soft AP mode on this works fine. On the other hand, v4.00.1 is much more compatible, however you should take care when cutting off the power since it has a potentially disastrous bricking problem if you cut the power when flash writing is in progress - the module may lock its memory forever.
I recommend registering and opening a Microchip ticket which usually will be answered within two business days and they're quite supportive. Their firmware update cycle is however quite long, and it usually takes a year or so for a new update.

Serial Port device protocol safe practice: Identification, polling

I'm creating a simple device that sends data to a Windows PC over serial COM ports.
I'd like the software to be able to scan the available COM ports until it recognizes the device. The problem is, if the PC tries to initiate the handshake with a device other than mine, it may interpret the commands [wrongly, of course].
The only solution I see is for my device to periodically broadcast some sort of identifier, perhaps 5 times per second or so, so the application only needs to listen for that identifier rather than risk corrupting another device also connected to a COM port. When the application loads, it listens on each available COM port until the device is recognised. Does this sound reasonable?
Thanks
IMO whatever the direction on which you initiate the handshake, the problem will be the same.
If you send your handshake from your device and another application on your PC is listening to the corresponding serial port, it also has risks to badly interpret the data you are sending.
So I would say that software on both side should be protected against incoherent data they receive from the outside.

How does a system's TCP/IP stack differentiate between multiple programs connecting to the same address and port?

Suppose two web browsers are running on the same computer and are accessing the same website (in other words, accessing the same IP address on the same port).
How does the operating system recognize which packets are from/for which program?
Does each program have a unique id field in the TCP header? If so, what is the field called?
The two programs are not actually accessing the "same port." For purposes of TCP, a connection is defined by the tuple (src_ip,src_port,dst_ip,dst_port).
The source port is usually ephemeral, which means it is randomly assigned by the OS. In other words:
Program A will have:
(my_ip, 10000, your_ip, 80)
Program B will have:
(my_ip, 10001, your_ip, 80)
Thus, the OS can see those are different "connections" and can push the packets to the correct socket objects.
the source port number will be different even if the destination port number is the same. the kernel will associate the source port number with the process.
When the client opens a connection to destination port 80, it uses an arbitrary unused source port on the local machine, say 17824. The web server then responds to that client by sending packets to destination port 17824.
A second client will use a second unused port number, say 17825, and so the two sockets' packets will not be mixed up since they'll use different port numbers on the client machine.
Christopher's answer is partially correct.
Programs A and B actually have a handle to a socket descriptor stored in the underlying OS's socket implementation. Packets are delivered to this underlying socket, and then any process which has a handle to that socket resource can read or write it.
For example, say you are writing a simple server on a Unix like OS such as Linux or Mac OSX.
Your server accepts a connection, at which point a connection consisting of
( src IP, src Port, dest IP, dest Port )
comes in to existence in the underlying OS socket layer. You then fork a process to handle the connection - at this point you now have two processes with handles to the socket both of which can read / write it.
Typically ( always ) the original server will close it's handle to the socket and let the forked process handle it. There are many reasons for this, but the one that is not always obvious to people is that when the child process finishes it's work and closes the socket the socket will stay open and connected if the parent process still has an open handle to it.
By port number.
IP address is used to identify computer, and port is used to identify process(application) within the computer. When a port is used by one process, other processes can't use it any more. So if any packet is sent to that port, only the owner of that port can handle that packet.
Connections are identified by a pair of endpoints.
– Endpoint means (ip, port)
Os assigns random number as src port number so, when packet travels to the receiving side, it is treated as different process's msg, since src port numbers are different.

Wavecom GSM modem as a TCP client

I've been trying to do TCP communication using my Wavecom Fastrack modem. What I want to achieve is make the modem connect to a specified TCP server port to enable me to transfer data to and from the server. I found some information on than in the user's guide.
Basing on the information you can find on page 66 I created an application that opens the serial port to which the modem is connected and writes the following AT commands:
AT+WIPCFG=1 //start IP stack
AT+WIPBR=1,6 //open GPRS bearer
AT+WIPBR=2,6,11,"APN" //set APN of GPRS bearer
AT+WIPBR=2,6,0 //username
AT+WIPBR=2,6,1 //password
AT+WIPBR=4,6,0 //start GPRS bearer
AT+WIPCREATE=2,1,"server_ip_address",server_port //create a TCP client on port "server_port"
AT+WIPDATA=2,1,1 //switch do data exchange mode
This is exactly what the user's guide says. After the last command is sent to the modem, the device switches to data exchange mode and from then on everything what is written to the serial port opened by my application should be received by the server and everything the server sends should appear in the input buffer of that port.
The thing is that I did not manage to maintain stable bidirectional communication between the server and my modem. When I write some data to the serial port (only a few bytes), it takes a lot of time before the data appears on the server's side and in many cases the data does not reach the server at all.
I performed a few tests writing about 100 bytes to the serial port at once. Logging the data received by my server application I noticed that the first piece of data (8-35 bytes) is received after a second or two. The rest of the data appears in 2-5 seconds (either as a whole or in pieces of the said size) or does not appear at all.
I do not know where to look for the reason of that behaviour. Did I use wrong AT commands to switch the modem to TCP client mode? I can't believe the communication may be so slow and unstable.
Any advice will be appreciated. Thank you in advance.
what OS are you running? Windows does a pretty good job of hiding the messy details of communicating with the GPRS modem, all you have to do is create a new dial-up connection. To establish the connection you can make a call to the Win32 RasDial function. Once connected, you can use standard sockets to transfer data on a TCP port.
i have been using wavecomm modem for 2 years now.As far as i know from my experience is that if you are able to send some of the data then you can send all of the data.
the problem might be in the listening application which receives the data on the server side.
It could be that it is unable to deal with the amount of data that you are trying to send.
try sending the same data in smaller busts
with some delay in between them,then you might receive all data intact.

Resources