I have a box, which sends UDP response after receiving UDP packet.
I finally found example
how to implement UDP server.
It receives UDP packets okay.
There is a button in my app.
If I tap it I sends UDP packet to the box,
but I don't get the resonse.
I see that the box receives this packet
from my Android device and sends the response.
My UDP client is below:
public class AsyncSendUdp extends AsyncTask<String, Void, Boolean> {
InetAddress inet_addr;
DatagramSocket socket;
#Override
protected Boolean doInBackground(String... arg0) {
byte[] ip_bytes = new byte[]{(byte) 192, (byte) 168, (byte) 0, (byte) 11};
try {
inet_addr = InetAddress.getByAddress(ip_bytes);
} catch (UnknownHostException e) {
e.printStackTrace();
}
char[] bufc = {1, 2, 3, 4};
byte[] buffer = new byte[4];
for (int i = 0; i < 4; i++) {
buffer[i] = (byte) bufc[i];
}
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, inet_addr, 0xbac0);
try {
socket = new DatagramSocket();
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}
I send as follows:
new AsyncSendUdp().execute("mmm");
I don't understand where is the problem.
Any ideas please!
You're never actually reading for incoming messages. You'll want something like:
byte[] inBuffer = new byte[N];
DatagramPacket inPacket = new DatagramPacket(inBuffer, inBuffer.length);
while (!exitCondition) {
socket.receive(inPacket);
// do something with your received packet
}
Related
My Android app needs to know the ip of the machine running the server on my local network. My plan is to broadcast an UDP packet in my app and to send a packet back from the server, so the app know the ip.
This is my code on Android:
...
new SendUDPTask().execute();
...
/************ getBroadcastAddress: know where to send the signal to find the server ***********/
private InetAddress getBroadcastAddress() {
//setup
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
DhcpInfo dhcp = wifiManager.getDhcpInfo();
//complicated stuff
int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
byte[] quads = new byte[4];
for (int k = 0; k < 4; k++)
quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
//return result
InetAddress result = null;
try {
result = InetAddress.getByAddress(quads);
} catch (UnknownHostException e) {
e.printStackTrace();
}
return result;
}
/************ sendUDP: here e send the packet that will allow us to find the server ***********/
private DatagramPacket sendUDP(String req, int port) throws IOException {
DatagramSocket socket = new DatagramSocket(port);
socket.setBroadcast(true);
InetAddress broadcastAddress = getBroadcastAddress();
DatagramPacket packet = new DatagramPacket(req.getBytes(), req.length(), broadcastAddress, port);
socket.send(packet);
byte[] buf = new byte[1024];
packet = new DatagramPacket(buf, buf.length);
socket.setSoTimeout(3000);
//We wouldn't want to think our own message is the server's response
String myAddress = getMyAddress();
socket.receive(packet);
while (packet.getAddress().getHostAddress().contains(
myAddress))
{
socket.receive(packet);
}
socket.close();
return packet;
}
/***************************** getMyAddress: the device's address *****************************/
public String getMyAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress())
return inetAddress.getHostAddress();
}
}
}
catch (SocketException e) {
e.printStackTrace();
}
return null;
}
private class SendUDPTask extends AsyncTask<String, Void, DatagramPacket> {
private Exception exception;
protected DatagramPacket doInBackground(String... params) {
try {
DatagramPacket packet = sendUDP("Ping", 31415);
Log.d("GJ", packet.getAddress().getHostAddress().toString());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(DatagramPacket packet) {
}
}
This is my code on my computer (Node.js):
var PORT = 31415;
var HOST = '127.0.0.1';
var dgram = require('dgram');
var server = dgram.createSocket('udp4');
server.on('listening', function () {
var address = server.address();
console.log('UDP Server listening on ' + address.address + ':' + address.port);
});
server.on('message', function (message, remote) {
console.log(remote.address + ':' + remote.port + ' - ' + message);
});
server.bind(PORT, HOST);
I am not sending back anything yet, but I should see the console.log. I don't see anything, which must mean the packet didn't arrive.
Does anyone have an idea?
Thanks a lot
If you bind the socket to loopback (127.0.0.1) interface you won't receive messages broadcasted in the network (192.168.1.255 in this case). In the nodejs server bind the socket to INADDR_ANY.
I want to send data like device Ip Address over wifi....
For achieving goals i write the following code
public void run() {
try {
DatagramSocket socket = new DatagramSocket(DISCOVERY_PORT);
socket.setBroadcast(true);
socket.setSoTimeout(TIMEOUT_MS);
sendDiscoveryRequest(socket);
listenForResponses(socket);
} catch (IOException e) {
Log.e(TAG, "Could not send discovery request", e);
}
}
public void sendDiscoveryRequest(DatagramSocket socket) throws IOException {
String data = "Test Data";
Log.d(TAG, "Sending data " + data);
DatagramPacket packet = new DatagramPacket(data.getBytes(), data.length(),
getBroadcastAddress(), DISCOVERY_PORT);
socket.send(packet);
}
public void listenForResponses(DatagramSocket socket) throws IOException {
byte[] buf = new byte[1024];
try {
while (true) {
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String s = new String(packet.getData(), 0, packet.getLength());
Log.d(TAG, "Received response " + s);
}
} catch (SocketTimeoutException e) {
Log.d(TAG, "Receive timed out");
}
}
InetAddress getBroadcastAddress()
{
try
{
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
DhcpInfo dhcp = wifi.getDhcpInfo();
// handle null somehow
int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
byte[] quads = new byte[4];
for (int k = 0; k < 4; k++)
quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
return InetAddress.getByAddress(quads);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
But it return the Ip Address of the device where it is currently running....and receives the same data that it sends.....any way to send data and receive data to a wifi connected android device? Please help me with this...
c# Use tcp socket Send message to Android:
string data = "my message....";
byte[] msg = Encoding.UTF8.GetBytes(data);
//for example msg Length is 5210 bytes
client.socket.SendBufferSize = 500000;
socket.Send(msg, msg.Length, SocketFlags.None);
Android receive message from c# server-side:
socket = new Socket(ServerIP, ServerPort);
socket.setReceiveBufferSize(500000);
isReceive = true;
receiveThread = new ReceiveThread(socket);
receiveThread.start();
private class ReceiveThread extends Thread{
private InputStream inStream = null;
ReceiveThread(Socket socket){
inStream = socket.getInputStream();
}
#Override
public void run(){
while(isReceive){
byte[] buffer = new byte[99999];
try {
//only receive 2896 bytes?
int size = inStream.read(buffer);
} catch (IOException e) {
unConnSocket();
}
}
}
}
why the size only receive 2896 bytes?
Your Android code has no way of knowing how many bytes the C# code is sending. inStream.read() is reading only the bytes that are currently available on the socket at that moment. You should have the C# code send the string length before sending the string data, so that the Android code knows how many bytes to expect, eg:
string data = "my message....";
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
int dataLen = IPAddress.HostToNetworkOrder(dataBytes.Length);
byte[] dataLenBytes = BitConverter.GetBytes(dataLen);
socket.Send(dataLenBytes);
socket.Send(dataBytes);
private class ReceiveThread extends Thread
{
private DataInputStream inStream = null;
ReceiveThread(Socket socket)
{
inStream = new DataInputStream(socket.getInputStream());
}
#Override
public void run()
{
while (isReceive)
{
try
{
String s;
int size = inStream.readInt();
if (size > 0)
{
byte[] buffer = new byte[size];
inStream.readFully(buffer);
s = new String(buffer, "UTF-8");
}
else
s = "";
// use s as needed ...
}
catch (IOException e)
{
unConnSocket();
}
}
}
}
Because TCP is a byte stream protocol and isn't obliged to deliver you more than one byte at a time.
You have to loop.
I quote from Linux man recv(2):
The receive calls normally return any data available, up to the requested amount, rather than waiting for receipt of the full amount requested.
I want to execute a udp receiver on eclipse. But its not working. The udp sender works properly and the packets are sent through the specific port. But emulator is not able to receive any packets through a udp sender. Help needed.
i don't know what your scenario is but according to my scenario i just setup a UDP server on my system(Windows 7) using php script and successfully sended and received UDP packets from android emulator with the following code.
String receivedString="";
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
sendData = stringToBeSended.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData,
sendData.length, IPAddress, port);
DatagramSocket clientSocket;
try {
clientSocket = new DatagramSocket();
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
clientSocket.receive(receivePacket);
receivedString = new String(receivePacket.getData());
clientSocket.close();
} catch (SocketException e) {
Log.v("SocketExceptionOccured", e.toString())
e.printStackTrace();
} catch (IOException e) {
Log.v("IOExceptionOccured", e.toString())
e.printStackTrace();
}
Toast.makeText(getBaseContext(), receivedString, Toast.LENGTH_LONG).show();
I am currently sending out a DatagramPacket on a DatagramSocket and I receive just fine.. the problem is that I am receiving the packet I sent out. If I call the receive twice then it times out. Is there a way to ignore the first packet and receive the second.
Here is my code..
socket = new DatagramSocket(8001);
socket.setBroadcast(true);
socket.setReuseAddress(false);
DatagramPacket packet = new DatagramPacket(databytes, 7,
getBroadcastAddress(), 8001);
socket.send(packet);
String localAddress = socket.getLocalAddress().toString();
byte[] buf = new byte[1024];
DatagramPacket receivepacket = new DatagramPacket(buf, buf.length);
socket.setSoTimeout(5000);
String temp = "";
String delims = "[/]";
while(true)
{
try{
socket.receive(receivepacket);
temp = receivepacket.getAddress().toString();
temp = temp.split(delims)[0];
if(temp != localAddress)
{
}else
{
m_IPAddress = temp;
break;
}
}catch (SocketException e){
} catch (IOException e){
String temp1 = e.toString();
}
}
Check to see if the address is bound to one of your interfaces.