me and one of my coworkers are working on a simple socket communication between Android and Iphone application. The thing we achieved till now is I can send byte array to him in another thread and receive byte array in service. But the problem that we face is that I can't read the whole message which he is sending to if he don't close the socket. But I need that socket alive, so I can send him response if the data was ok or there were some problems. Here is how I am listening about his messages :
thread = new Thread(new Runnable() {
public void run() {
try {
serverSocket = new ServerSocket(5000);
while(state){
client = serverSocket.accept();
client.setKeepAlive(true);
// LOGS
Log.d("","receivedBufferSize : "+serverSocket.getReceiveBufferSize());
Log.d("","is connected : "+client.isConnected());
Log.d("","port : "+client.getPort());
Log.d("","ipadress : "+client.getInetAddress().toString());
InputStream is = client.getInputStream();
Log.d("","is Size : "+is.available());
byte[] bytes = toByteArray(is);
for(int i=0;i<bytes.length;i++){
Log.d("","bytes["+i+"] : "+bytes[i]);
}
}
serverSocket.close();
Log.d("","client socket : "+client.isClosed() + " serverSocket : "+serverSocket.isClosed());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
So if he don't close the application or don't close the socket, I am sitting on that log message : Log.d("","is Size : "+is.available()); and nothing really happens. After he close the socket I can see the bytes of received byte array.
Any idea what I am doing wrong or any kind of suggestions / help what can cause this?
Thanks in advance!
Actually the problem was on Iphone side, it was just a Input / Output Stream problems with Objective C implementation. So this piece of code is working properly.
Related
I have created an application to Android and Microsoft Hololens, where it is possible to send some GPS-data with bluetooth from an Android-phone to a Hololens (with Bluetooth LE Advertiser) and that works allright. But when I am trying to send other data from Hololens to Android, I have a problem that Android-phone can't discover Hololens, although these devices are paired. Is it even possible to send data from Hololens with bluetooth, or is there only something wrong in my code? Does Bluetooth LE Advertising support two-way data transfering?
I am guessing you have a BluetoothConnected thread in your android app with an InputStream (mine is mmInStream). Try using this as your 'run' function in the thread:
public void run() {
System.out.println("BT THREAD RUNNING");
mmBuffer = new byte[1024];
int numBytes; // bytes returned from read()
InputStreamReader mmInStreamReader = new InputStreamReader(mmInStream);
BufferedReader mmReader = new BufferedReader(mmInStreamReader);
// Keep listening to the InputStream until an exception occurs.
while (true) {
try {
// Read from the InputStream.
Thread.sleep(100);
String s = mmReader.readLine();
Thread.sleep(100);
//Static class that handles the response
BluetoothCommunications.responseHandler(s);
} catch (IOException e) {
System.out.println("Input stream was disconnected" + e);
main.disconnected();
break;
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
I am using Tcp Sockets For Communication Between CLR C++ (Server) to Android(Client) While using .Net For GUI.
While the data is communicated and received. Using a Background Worker in C++ Application
if(backgroundworker1->CancellationPending)
{
listenerSocket->Close(); // Listener Socket is Closed
netStream->Close();
serverSocket->Close();
serverSocket->Shutdown(SocketShutdown::Both);
e->Cancel;
break;
}
While in Android i am using Async Class for Execution and receiving text from socket to a Handler. While in Doinbackground Function i am using this code.
try
{
socket = new Socket(dstAddress, dstPort);
BufferedReader inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
do
{
try
{
if (!inputStream.ready())
{
if (message != null)
{
MainActivity.handler.obtainMessage(0, 0, -1,"Server: " + message).sendToTarget();
message = "";
}
}
int num = inputStream.read();
message += Character.toString((char) num);
Log.e(message,message);
}
catch (Exception classNot)
{
Log.e("Client TASK","classnot exception");
}
}
while (!message.equals("bye"));
inputStream.close();
socket.close();
}
I don't understand While am sending the Bye Message from the server and (Backgroundworker1->CancellationPending)
All server sockets are closed and Mobile Sockets are closed why is the UI Not Responding? Please Help..
The Problem was in Client in doinbackground Which calls the while loop again hence causing an exception because no data was received in the sockets and causing an exception. Finally added some sleep to the client that after some time the client query the server while if there is no message from the server the client shutdowns and shifted to postexecution function.
sorry for my bad english. I have to send and receive data from phone to radio using bluetooth pan interface on android. This is the code I've implemented to send, I've made it into the function DoInBackground() of AsyncTask:
try
{
ds = new DatagramSocket();
byte buf[] = "Ciao".getBytes();
DatagramPacket msg = new DatagramPacket(buf, buf.length, InetAddress.getByName(add), p);
ds.send(msg);
}
and it works perfectly. Now I have to wait 100 seconds the answer of the radio. I decide to implement it with this code:
try
{
ds.setSoTimeout(10000);
while(true)
{
try
{
ds.receive(dp);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
catch (IOException e)
{
}
but there are three questions:
1. I need to receive the packet at 192.168.11.2 and 1234 port, but when I declared datagramsocket I set it void, because if i put port and address, send code doesn't work;
2. How can I manage the packet I've received by the radio? I don't need to use address and port bytes;
3. Why have I put the timeout before the loop?
Thank you for the answers.
1) Create the datagram socket with just the port number you are after. DatagramSocket(p);
2) You have a DatagramPacket with a bytebuffer of the size of the response and the length of the response i.e:
int responseLength = 1024;
byte[] responseData = new byte[responseLength];
DatagramPacket response = new DatagramPacket(responseData, responseLength);
After receiving into this datagram packet you need to convert it into same object that it was sent as. Something like this maybe:
String s = new String(response.getData());
3) The setSoTimeout doesn't cause the message to wait for 100s, it is just saying that after 100s if nothing has been read in by the receive() then it will timeout. This only needs to be set once per connection, setting this multiple times during the loop shouldn't be done.
Hope this helps
I'm developing an Android real-time-data app that sends data (floats and ints) to a server on the local subnet via a TCP socket. The problem I'm facing is that after sending some data simultaneously the socket doesn't send anymore data at all. I debugged the app and it shows that data is being sent but doesn't show up on the server. After this happens if I close the connection the server doesn't even get the notification that the connection has been terminated which it should according to my design model. Meanwhile I get an exception on the app saying it can not write to a broken pipe. This tells me that the problem is with the app because I also did test using a desktop app and I can send huge amounts of data to the server and it gets delivered.
And please keep in mind that the data size I'm talking about here is 252 bytes per packet.
Here's my class I'm using. (This runs in an AsyncTask object )
public class Network
{
private Socket handle;
public static enum TASK
{
TASK_CONNECT, TASK_SEND, TASK_CLOSE
}
public Network()
{
}
public String lastError = "";
public boolean Connect(String host, int port)
{
try
{
lastError = "Connecting to server.";
handle = new Socket(host, port);
handle.setTcpNoDelay(true); //
handle.setSendBufferSize(SIZE_OF_PACKET); ///==> These don't seem to help at all
handle.setKeepAlive(true); ///
return true;
}catch(IOException e)
{
lastError += e.getMessage() != null ? " "+ e.getMessage() : "";
return false;
}
}
private void err(String e){
System.err.println(e);
}
private boolean SendPacket(byte buffer[])
{
OutputStream oStream = null;
err("sending: " + buffer.length + " bytes");
try
{
lastError = "Obtaining output stream.";
oStream = handle.getOutputStream();
lastError = "Error sending data.";
oStream.write(buffer);
oStream.flush();
return true;
}catch(Exception e)
{
lastError += e.getMessage() != null ? " "+ e.getMessage() : "";
}
return false;
}
public void Close()
{
try{ handle.close(); handle = null; }catch(Exception e){} // swallow exception
}
}
I send my data in a loop depending on how many numbers I have. I tried a Google search but didn't find anything relevant. Has anyone experienced this before? It's making me mad now.
EDIT: Wireshark shows incoming "red" packets that don't reach the desktop app (server)
Look at this picture.
You can see the first few have Len > 0 the red ones have 0.
I think it's time Google interfaced the USB so we can use it. At least that'd would have been my first option.
Should you not be calling oStream.close() after you flush the stream, given that you never use it again?
Also, you say that this is being run in an AsyncTask object. Is it possible that multiple threads could be attempting to send packets at the same time? If so, you might need some form of synchronisation around the SendPacket method.
Ok. I solved the issue by using UDP instead. Thank you all.
But I still didn't find the source of the problem.
I'm designin an application in Android that connects the mobile to a bluetooth device. I can do this, as I open a BluetoothSocket like this:
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
socket = (BluetoothSocket) m.invoke(device, 1);
socket.connect();
Where device is the paired device with the mobile bluetooth desired. The thing is, this external device is a bit special, and it has different times for writing and answering to the mobile, so I need to put some timeouts on my socket for reading and writing, but I've searched a lot and it seems like BluetoothSocket doesn't support this.
Can anybody tell me a different way to admin timeouts on reading and writing to the port on the BluetoothSocket class for Android?
Thank you!
There are many Exceptions a socket or it's streams can throw. The socket.connect() for example can throw a ConnectTimeoutException. Every method in the BluetoothSocket context can through an IOException just take a look at the documentation and you will see which exception you have to catch in order to make your program work properly.
Here is the code for reading and writing code:
Writng code on port:
try
{
// Enviamos los bytes
DataOutputStream dOut = null;
dOut = new DataOutputStream(socket.getOutputStream());
// Send message
dOut.writeBytes(res);
dOut.flush();
}
catch (IOException e)
{
Dialogs.showErrorDialog("Error al recuperar la fecha y hora del dispositivo Nonin.", this);
}
Then, reading from port until response available:
DataInputStream dIn = null;
// We receive the answer
try
{
dIn = new DataInputStream(socket.getInputStream());
}
catch (IOException e)
{
Dialogs.showAlertDialog("An exception occured during bluetooth io stream creation", this);
}
while (true)
{
try
{
String data = dIn.readLine(); // readLine();
byte[] total = EncodingUtils.getBytes(data, "ASCII");
Dialogs.showInfoDialog("Mensaje ok: " + data.toString(), this);
}
catch (IOException e)
{
break;
}
}
The thing is that I think the writing works, as I convert the desired string into bytes, and it works. But then, when I'm waiting for response, it mixes further responses with the desired, and I think this is because timings.
There's no more code in the middle related with sockets. First, I create it. Then, I try to send a byte String. Then I wait until I receive the answer for the byte String that I just sent.
Thank you in advance.