Why do the UDP recipient recevie the same packet in twice? The UDP sender just send one packet to the recipient, but the recipient receive the packet in twice and the two packet are same.The sender and recipient are runned in the differnt device.The sender APP is runned in the android device and the receipient is runned in the iOS device. How to explain this case and how to fix it?
From http://en.wikipedia.org/wiki/User_Datagram_Protocol
UDP uses a simple transmission model with a minimum of protocol mechanism.
It has no handshaking dialogues, and thus exposes any unreliability of the
underlying network protocol to the user's program. As this is normally IP
over unreliable media, there is no guarantee of delivery, ordering or
duplicate protection.
If you want to avoid such scenarios, you'll have to use TCP instead.
Related
I'm making an android application where I'm intercepting the TCP packets sent from the phone/to the phone (UL/DL). I'm getting the information like length of the packets, port etc but I can't find a way to get the band at which the packets are being sent.
Any lead would be appreciated.
I am developing a VoIP service where two devices can have an audio conversation.
I have been reading about signalling protocols like SIP. I understand the power of SIP but I prefer to have my own signalling protocol since my service will be very basic and will not require the full power of SIP.
As far as I understand, the main purpose of SIP and other protocols is to find the address of the remote party. This information I can get from my server, so no need for SIP here.
Establishing the connection from the caller should be relatively easy.
The problem I am facing however: How can I make the callee Android system listen for RTP packets specific to my app? I need this so I can fire up an intent to deal with answering the call etc.
A ServerSocket has been suggested, but I am not using TCP, and I am trying to make a client-to-client connection, not a server-client one.
SIP is not only used to find the IP address of remote party but also to agree on ports involved in media communication.
For 1-to-1 calls, when caller establishes connection it sends SIP INVITE to callee IP and SIP port. Caller knows that IP because it can query for it from the Registrar server for example.
The SIP INVITE sent from caller to callee has RTP/RTCP ports of caller stored in SDP payload of SIP INVITE message.
When receiving SIP INVITE the callee immediately responds to caller with 180 Ringing, the callee then may display an alert indicating that incoming call is received. Assuming that user accepts the call 200 OK is generated and sent to caller. This 200 OK message has SDP payload with RTP/RTCP ports that will be used by callee to listen for media packets. When 200 OK is received by caller both parties know the ports that will be used for the communication.
If I were you I wouldn't invent any protocols. I would rather try using 3rd party libraries such as pjsip, sofia-sip or some Android SIP stack.
If this is not the case, I would try to adapt the above message flow to your protocol. The problem is that the caller has to know in advance callee's IP and port where signalling message has to be sent. This may be difficult to achieve without any server involved (to query for callee port and IP).
In the Bluetooth HDP sample by Google, it seems it only try to initiate connections to the device (so that the phone would be the client and the health device would be the server).
However, the health device that I have (Omron 708-BT) is only designed to be a Bluetooth client but not a server - it can only initiate connections but it can't listen to incoming connections.
How can I make my phone listen for incoming HDP connections similar to how it's done for SPP here?
There is a sample app based on Antidote 11073 stack that does exactly that:
https://github.com/brasileiroaraujo/HealthServiceAndroid
Basically you need to register a Handler in BluetoothHDPService (by sending a MSG_REG_CLIENT). In the example source, handler name is mIncomingHandler.
The handler gets messages like BluetoothHDPService.STATUS_CREATE_CHANNEL, when a device connects and creates a HDP channel.
Don't forget to register the data types you accept by sending BluetoothHDPService.MSG_REG_HEALTH_APP messages. Data type for blood pressure is 0x1007, I think.
I am working on Android project which communicates over TCP/IP. Communication works on specific protocol - this protocol is message oriented.
android device sends message to server via socket
server sends answer message to android device
It is not problem but I have a few parlous questions.
I don't have any idea how to solve connection interrupts (wifi, edge, change wifi to edge over open socket, ...) and connection timeouts? If android device sends 1 message and in this moment are connection problems - then android device sends different message (other request) - it is guaranteed that answers will be delivered in correct sequence?
I tried set timeout for socket object but it didn't work. I dont know why but if I set timeout to 5 seconds and I turned off the server before I sent message - it took more than 5 second before she came exciption.
I didn't found any articles on internet about this problems.
Thank you very much.
For TCP sockets the way you can get timeouts is by using select() or poll(),in Android you have to use SocketChannel() (java.nio) class to deal with non-blocking sockets. They both can query a socket for a specific period (10 or 20 seconds for example) and can tell you if it is writeable (you can use send()) or readable (there is data to be read recv()). Also the select() command will tell you if the socket has an error, most probably a broken connection. When you get such an error (except an interrupted signal, this one should be ignored and reissue the select), all you can do is close the socket and reopen a new one with the server, there is no way, as far as I know, to recover a broken connection, although, if you've implemented in the protocol, you can resume where you left off when the socket was broken. I don't know how you've implemented the protocol, but most of them will required a positive ACK (acknowledge) from the receiver before going on with another message. Also, when establishing a connection the client should specified if it a brand new connection or a broken one and act accordingly.
The idea is:
The sender sends a header specifying the command to process and the length of the data it's going to send after the header, the receiver receives the header and the data, once it process it, it sends a response ACK packet to the sender with a positive value to acknowledge the message, optionally with some data in case it's necessary. If after a reasonable period of time you don't receive the ACK packet then you may resend the same data again until you receive the positive ACK.
There could be the situation where the client sends a message, the server receives it and processes it, but when the server sends the positive ACK packet the connections breaks and the client never receives the packet, so it will resend the same message again once the connections is reestablished. To avoid this situation, it's necessary to send a message ID (an int which increments for every message sent) in the header to identity it.
I know it sounds difficult and it's in fact. If the connection is on the same network (intranet) it works nicely but, when the communication is on the internet, you may face a lot of problems and situations which you can't control, so it's necessary a well defined protocol where you can recover from broken connections and the transactions/messages won't be duplicated.
I'm trying to figure out how to search for other devices logged into a wifi network that are hosting the application on a specific port.
How can I detect the presence of these other devices without knowing their address or even necessarily the port they are hosting on?
Once discovered, I should be able to contact the device and establish a client-server connection with it using SocketChannels.
Note: This application is meant to work with Android devices pre-ICS. So no Wifi-Direct.
You can definitely send a probe packet to broadcast (255.255.255.255) on a well-known port on which all peers listen. This is a good old technique for easy discovery. Others incluse SSDP or UPnP.
Be aware that 255.255.255.255 works only for UDP broadcasts
[Add]
I prefer expanding my answer rather than commenting.
1. Who should initiate a broadcast?
You can choose your favourite broadcast model. They are all interchangeable.
Model 1 is "job offering" and in my opinion is my favourite. You open a listening socket on your server application and then periodically send an advertising or better announcement broadcast message telling everyone that an open service is available at a certain IP/port (the port is not required to be static). Any peer interested in communication simply connects to the specified endpoint to use the service.
Model 2 is "job seeking", in which the server remains silent. When a client wants to connect, it broadcasts a generic seek message. Any server available receives the message and either replies (unicast) or else broadcasts the above mentioned announcement message.
Model 2a is "reverse job seeking" where a client broadcasts a request for service not as a generic message but including its endpoint. The server then connects to the client endpoint but the protocol continues as the client node is requesting a service from the server node. They act as reverse-roles TCP peers.
2. How often?
It depends on several factors. I'm not able to help you choose the final number of milliseconds, but I can show you all of the factors. First, how long should a client wait to tell the user that the scan for available services is "finished"? You may think "instantly", or "1 second", but bear in mind that broadcast packets tend to overload the network according to the number of servers available in a community.
If you choose model 1, start listening for available services ASAP (ie when application starts) and then periodically remove from the list those services whose heartbeat (another technical name for the broadcast packet) is not received within T*2 or T*3 timeframe where T is your timeout. A manual scan is generally supposed to be completed within T*1.5 or T*1.2 depeding on how large is T