Android Broadcast UDP Looping - android

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.

Related

Sending datagram - network unreachable

I'm trying to broadcast udp packets between two Android devices on a hotspot.
I have a client that set up the hotspot, and a server that is connected to the hotspot. Sending a package from the client and receiving that packet on the server is working. But when I try to reply from the server, I get a SocketException, saying network is unreachable. I've checked the IP address and port number and both should be correct (I'm assuming the port is correct because it was taken from the packet itself).
The code for the server and client is below. Can anyone see where the code is going wrong or if it's just a network connectivity issue?
Client:
try {
//Open a random port to send the package
c = new DatagramSocket();
c.setBroadcast(true);
byte[] sendData = "DISCOVER_MV_REQUEST".getBytes();
try {
InetAddress addr = getIpAddress();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, getBroadcast(addr), 8888);
c.send(sendPacket);
} catch (Exception e) {
c.close();
e.printStackTrace();
return null;
}
// Broadcast the message over all the network interfaces
Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) interfaces.nextElement();
if (networkInterface.isLoopback() || !networkInterface.isUp()) {
continue; // Don't want to broadcast to the loopback interface
}
for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
InetAddress broadcast = interfaceAddress.getBroadcast();
if (broadcast == null) {
continue;
}
// Send the broadcast package!
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, broadcast, 8888);
c.send(sendPacket);
} catch (Exception e) {
c.close();
e.printStackTrace();
return null;
}
}
}
//Wait for a response
byte[] recvBuf = new byte[15000];
DatagramPacket receivePacket = new DatagramPacket(recvBuf, recvBuf.length);
c.receive(receivePacket);
//Check if the message is correct
String message = new String(receivePacket.getData()).trim();
if (message.equals("DISCOVER_MV_RESPONSE")) {
//DO SOMETHING WITH THE SERVER'S IP (for example, store it in your controller)
Log.v("SOCKET", "got correct response");
c.close();
return "correct";
} else {
c.close();
Log.v("SOCKET", "wrong response");
return "wrong";
}
} catch (Exception e) {
c.close();
e.printStackTrace();
return null;
}
Server:
try {
//Keep a socket open to listen to all the UDP trafic that is destined for this port
socket = new DatagramSocket(8888, InetAddress.getByName("0.0.0.0"));
socket.setBroadcast(true);
while (true) {
//Receive a packet
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
socket.receive(packet);
//See if the packet holds the right command (message)
String message = new String(packet.getData()).trim();
if (message.equals("DISCOVER_MV_REQUEST")) {
byte[] sendData = "DISCOVER_MV_RESPONSE".getBytes();
//Send a response
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, packet.getAddress(), packet.getPort());
socket.send(sendPacket); //where the error happens
socket.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}

why android only receive 2896 bytes on c# tcp socket?

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.

A UDP receiver on android

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();

Wifi Chat between android and PC

I was working on a application where i needed to establish a communication between android and PC to transfer some data over wi-fi. I am able to communicate between two PC's over wifi. So code from PC side is ready. I needed a reference to use Wifi from android side. Something similar to bluetooth chat is helpful. I am able to scan Wifi networks present in android but not able to proceed further.
Cheers
This one receives a file
private String ReceiveFile() {
try {
ServerSocket socket = new ServerSocket(port);
socket.setSoTimeout(5000);
Socket os = null;
try {
os = socket.accept();
} catch (SocketTimeoutException t) {
if (!socket.isClosed()) socket.close();
return "TIMEOUT";
}
InputStream bos = os.getInputStream();
FileOutputStream fos = new FileOutputStream(FILENAME);
DataOutputStream bw = new DataOutputStream(fos);
int Total = 0;
byte[] buffer = new byte[4096];
int read;
while (true) {
read = bos.read(buffer);
if (read <= 0) break;
bw.write(buffer, 0, read);
Total = Total + read;
}
if (!socket.isClosed()) socket.close();
return "SUCCESS";
} catch (Exception e) {
e.printStackTrace();
return "FAILURE";
}
}
Without knowing what you trying to achieve it is difficult to be more specific but this snippet receives a short data burst.
DatagramSocket serverSocket = new DatagramSocket(PORTNUMBER);
byte[] receiveData = new byte[50];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.setSoTimeout(5000);
serverSocket.receive(receivePacket);
serverSocket.close();

Why an application works during debugging but doesn't work on run?

I have a client in Android and server in C#, they communicate through socket.
I have this problem - if I run my client app in debug mode and place a breakpoint in right place - it works perfectly, but without it it doesn't.
Client sends adress of an image to server, server makes a thumbnail of it, converts it to byte[] and sends it back. Client gets the byte[], converts it back into image and shows it.
I've also found out that when it doesn't get the right byte[] its size is 2896 and sometimes 1448, no matter what the original size of the array sent was.
Here's the client:
private void connectSocket(String a){
try {
InetAddress serverAddr = InetAddress.getByName("192.168.1.2");
Socket socket = new Socket(serverAddr, 4444);
String message = a;
flag = 0;
if(a.indexOf(".jpg")>0){
flag = 1;
}
ListItems.clear();
if(!a.equalsIgnoreCase("get_drives"))){
//.....
}
if(!ListItems.isEmpty()){
if(ListItems.get(0).matches("^[A-Z]{1}:$")){
ListItems.set(0, ListItems.get(0)+"\\");
}
}
PrintWriter out = null;
BufferedReader in = null;
InputStream is = null;
try {
out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
is = socket.getInputStream();
out.println(message);
String text = "";
String finalText = "";
if(flag!=1){
while ((text = in.readLine()) != null) {
finalText += URLDecoder.decode(text, "UTF-8");
}
String[] result = finalText.split("#");
for(int i = 0; i<result.length; i++)
ListItems.add(result[i]);
}
if(flag ==1){
byte[] buffer = new byte[9999];
//placing breakpoint at the next line or before it makes it work fine
int size = is.read(buffer);
//but placing a breakpoint at the line below doesn't make it work
//it starts getting another byte array
byte[] bufffer2 = new byte[size];
for(int g = 0; g<size;g++){
bufffer2[g] = buffer[g];
}
//is.read(bufffer2);
//int read = is.read(buffer);
image = (ImageView)findViewById(R.id.imageView1);
//while ((text = in.readLine()) != null) {
// byte[] b = in.readLine().getBytes();
Bitmap bmp=BitmapFactory.decodeByteArray(bufffer2,0,bufffer2.length);
image.setImageBitmap(bmp);
//}
}
adapter.notifyDataSetChanged();
} catch(Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
socket.close();
}
} catch (UnknownHostException e) {
Log.e("TCP", "C: UnknownHostException", e);
e.printStackTrace();
} catch (IOException e) {
Log.e("TCP", "C: IOException", e);
e.printStackTrace();
}
}
Here's the server:
public class serv {
public static void Main() {
try {
IPAddress ipAd = IPAddress.Parse("192.168.1.2");
TcpListener myList=new TcpListener(ipAd,4444);
m:
myList.Start();
Socket s=myList.AcceptSocket();
byte[] b=new byte[100];
int k=s.Receive(b);
char cc = ' ';
string test = null;
Console.WriteLine("Recieved...");
for (int i = 0; i < k-1; i++)
{
Console.Write(Convert.ToChar(b[i]));
cc = Convert.ToChar(b[i]);
test += cc.ToString();
}
string[] response = null;
ASCIIEncoding asen = new ASCIIEncoding();
switch (test)
{
default:
MyExplorer(test, s);
break;
}
s.Close();
myList.Stop();
goto m;
}
catch (Exception e) {
Console.WriteLine("Error..... " + e.StackTrace);
}
}
public static void MyExplorer(string r, Socket s){
Image imgThumb = null;
if (r.Contains(".jpg"))
{
Image image = null;
image = Image.FromFile(r);
// Check if image exists
if (image != null)
{
imgThumb = image.GetThumbnailImage(100, 100, null, new IntPtr());
s.Send(imageToByteArray(imgThumb));
byte[] b = imageToByteArray(imgThumb);
}
return;
}
}
public static byte[] imageToByteArray(System.Drawing.Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
return ms.ToArray();
}
}
The read(byte []) method in InputStream reads as many bytes as currently available. It does not necessarily mean that there won't be more bytes available later. So you need to do something like
while(true) {
int s = is.read(buffer);
if(s == -1) break;
// else
add read buffer to image array
}
extract image from image array
where "image array" is some byte array where you keep adding the read buffer until you reach then end of the stream.
The reason your code works with the breakpoint is that by the time you go through the debugger the whole stream is available, while in non-debug the whole stream is not yet available when you do the read.
The difference is likely due to the fact that on the debugger, you are able to slow and stop the application - this gives time for the server to respond to your call. It looks like you are not using any asynchronous methods to call connect socket (well, I can't see any evidence of this from your code anyway).
To fix this, you should try extending the AsyncTask object examples here
EDIT: #Carsten probably has the correct solution, but you should STILL use an AsyncTask if you are not already.

Categories

Resources