I am new to Programming with Java, and I am trying to send some value from 'Blueterm' application on Android and receive it on my Raspberry pi 3 via Bluetooth. Already raspberrypi3 has built in bluetooth and I am able to pair the 2 devices but I am not able to connect them and don't know how to start with the Java code. I hava tried ConnectedThread and AcceptThread but no progress, so if anyone could help me with this.
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.UUID;
import javax.bluetooth.*;
import android.bluetooth.*;
public class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
private UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public AcceptThread() {
BluetoothAdapter Badp= BluetoothAdapter.getDefaultAdapter();
if (Badp == null) {
// Device does not support Bluetooth
System.out.println("Bluetooth Not Supported");
}
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = Badp.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(socket);
try {
mmServerSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
private void manageConnectedSocket(BluetoothSocket socket) {
//acceptThread.cancel();
}
}
Related
I need to simulate a distributed system.
There is a controller and n worker computers.
The controller tells the computers when to start, and the computers will start connecting to other computers using sockets. The controller is connecting to the computers using threads. The computer will connect to other computers using threads as well.
Once they are connected to each other, they will send events to each other until they have generated x events. Once they reach x events, the computer will send a "Finish" message to the controller saying that it's done generating events, but will continue reading events from other computers.
My issue: The computers have successfully sent the Finish message to controller, except the last computer in the system. According to the logs, the last computer did send the Finish message to the controller, but the controller did not receive it. The other computers successfully sent the finish message to the controller.
If you need more information, I would be glad to provide. I have been working on this for hours and have no clue.
Computer.java
package timetableexchange;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Vector;
public class Computer {
// Constant system capacity
static final int MAX_SYSTEMS = 4;
// Computer's time-stamp vector
static Vector<Integer> timestamp = new Vector<Integer>();
// Computer's ID
static int identifier;
// Computer's Event Count
static int eventCount = 0;
// Computer's isAlive check
static boolean isAlive = true;
// Socket to Controller
Socket socketToController;
PrintWriter outputToController;
BufferedReader inputFromController;
String textFromController;
// Server Socket
ServerSocket serverSocket;
// Input and Output Clients
static ArrayList<ClientSocket> outputClients = new ArrayList<ClientSocket>();
static ArrayList<ClientConnection> inputClients = new ArrayList<ClientConnection>();
// Log
Log log;
public static void main(String[] args) throws IOException {
new Computer("127.0.0.1", 8000);
}
public Computer(String hostname, int port) throws IOException {
// Initialize time-stamp
for (int i = 0; i < MAX_SYSTEMS; ++i) {
timestamp.add(0);
}
// Connect to Controller
try {
socketToController = new Socket(hostname, port);
inputFromController = new BufferedReader(new InputStreamReader(socketToController.getInputStream()));
outputToController = new PrintWriter(socketToController.getOutputStream(), true);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
// Get Computer ID from Controller
while (true) {
try {
if (inputFromController.ready()) {
textFromController = inputFromController.readLine();
identifier = Integer.parseInt(textFromController);
break;
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
log = new Log("client" + identifier + ".txt");
// Read start message
while (true) {
try {
if (inputFromController.ready()) {
textFromController = inputFromController.readLine();
if (textFromController.equals("Start")) {
log.write("Computer is starting!");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
// Instantiate server socket
int socketPort = port + identifier + 1;
// System.out.println(socketPort);
serverSocket = new ServerSocket(socketPort);
log.write("Server Socket Instantiated");
// Instantiate sockets for other server sockets (computers) to send
for (int i = 0; i < MAX_SYSTEMS; ++i) {
if (i != identifier) {
Socket acceptedSocket = new Socket(hostname, port + i + 1);
ClientSocket socketToComputer = new ClientSocket (acceptedSocket);
outputClients.add(socketToComputer);
}
}
log.write("Client Sockets Instantiated\n");
// Accept sockets from server socket and add them into a list
for (int i = 0; i < MAX_SYSTEMS - 1; ++i) {
ClientConnection computerConn = new ClientConnection(serverSocket.accept());
computerConn.start();
inputClients.add(computerConn);
}
log.write("Server connected to clients");
Random rand = new Random();
// Generating events
int temp;
while (eventCount < 50) {
log.write("Generating Event");
int choice = rand.nextInt(5);
if (choice == 0) {
temp = timestamp.get(identifier);
++temp;
timestamp.set(identifier, temp);
} else {
int randC = rand.nextInt(outputClients.size());
ClientSocket cc = outputClients.get(randC);
cc.out.writeObject(new Event(identifier, timestamp));
}
log.write(timestamp.toString());
log.write("Done Generating Event");
eventCount++;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.write("Finished writing. Continue reading...");
/**
* ========THE ISSUE IS BELOW.===============
*/
synchronized (outputToController) {
outputToController.println("Finish");
outputToController.flush();
}
log.write("Sent Finish Message " + identifier);
// Wait for Tear Down Message
while (true) {
try {
if (inputFromController.ready()) {
textFromController = inputFromController.readLine();
if (textFromController.equals("Tear Down")) {
log.write("Tearing down....");
isAlive = false;
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.write("Computer shutting off....");
}
// client socket class (organizing)
public class ClientSocket {
Socket socket;
ObjectOutputStream out;
ObjectInputStream in;
public ClientSocket(Socket s) {
try {
this.socket = s;
this.out = new ObjectOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
log.write("Client Socket Created");
}
}
// send event thread
public class ClientConnection extends Thread {
Socket socket;
ObjectOutputStream out;
ObjectInputStream in;
Random rand = new Random();
public ClientConnection(Socket s) {
this.socket = s;
try {
out = new ObjectOutputStream (socket.getOutputStream());
in = new ObjectInputStream (socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run () {
while (isAlive) {
log.write("Reading events");
try {
Event event = (Event) in.readObject();
executeEvent(event.getFromID(), event.getTimestamp());
} catch (ClassNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(timestamp);
}
log.write("Finished Reading");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// execute the event
private void executeEvent(int from, Vector<Integer> x) {
int temp;
synchronized (timestamp) {
for (int i = 0; i < timestamp.size(); ++i) {
if (x.get(i) > timestamp.get(i)) {
timestamp.set(i, x.get(i));
}
}
temp = timestamp.get(from);
++temp;
timestamp.set(from, temp);
}
}
}
}
Controller.java
package timetableexchange;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Controller {
// Mutex Lock
public final static Object lock = new Object();
// Constant system capacity
static final int MAX_SYSTEMS = 4;
// Server connection threads to computers
static ArrayList<ServerConnection> conns = new ArrayList<ServerConnection>();
// Finished computers
static int finishedCount = 0;
// Server Socket
ServerSocket ss;
// Log Instance
Log log;
public static void main(String[] args) throws IOException {
new Controller(8000);
}
public Controller(int port) {
// Instantiate Log
log = new Log("server.txt");
// Instantiate Server Socket and Listen for Incoming Sockets
try {
ss = new ServerSocket(port);
log.write("Listening...");
// Accept computers until capacity
for (int i = 0; i < MAX_SYSTEMS; i++) {
Socket s = ss.accept();
log.write("Socket connected");
// Add to list
ServerConnection conn = new ServerConnection(i, s);
conns.add(conn);
conn.start();
}
// Notify all waiting threads to start
synchronized (lock) {
try {
Thread.sleep(1000);
lock.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private class ServerConnection extends Thread {
// Client Socket
Socket socket;
// Output stream
PrintWriter out;
// Input stream
BufferedReader in;
// ID for connected computer
int identifier;
public ServerConnection(int i, Socket s) {
// Instantiate properties
this.identifier = i;
this.socket = s;
try {
this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.out = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
log.write("Controller is connected to computer#" + identifier);
// Send ID to computer
out.println(identifier);
// Wait until notified
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Send Start Message to All Computers
sendAll("Start");
waitForFinish();
log.write("Computer#" + identifier + " is waiting for tear down.");
// If all computers sent the Finish message, send a Tear Down
while (true) {
if (finishedCount == conns.size()) {
log.write("Sending tear down to all computers");
sendAll("Tear Down");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* ==== RECEIVE FINISH MESSAGE FROM COMPUTERS ======
*/
private void waitForFinish() {
String clientInput;
while (true) {
try {
if (in.ready()) {
clientInput = in.readLine();
log.write(clientInput);
if (clientInput.equals("Finish")) {
finishedCount += 1;
log.write("Computer " + identifier + " is finished");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Send all "text" to all computers in the thread pool
private void sendAll(String text) {
for (int i = 0; i < conns.size(); ++i) {
ServerConnection conn = conns.get(i);
conn.out.println(text);
}
}
}
}
Controller Log: (notice that the log does not say computer 3 is finished)
Listening... (Listening for Computer)
Socket connected
Controller is connected to computer#0
Socket connected
Controller is connected to computer#1
Socket connected
Controller is connected to computer#2
Socket connected
Controller is connected to computer#3
Computer 2 is finished
Computer 1 is finished
Computer#2 is waiting for tear down.
Computer 0 is finished
Computer#1 is waiting for tear down.
Computer#0 is waiting for tear down.
Computer #0 Log: (I cut down the log because there was a lot of reading and writing event log statements)
Computer is starting!
Server Socket Instantiated
Client Socket Created
Client Socket Created
Client Socket Created
Client Sockets Instantiated
Server connected to clients
// A bunch of reading and writing events
Finished writing. Continue reading...
Sent Finish Message 0
Computer #1 Log:
Computer is starting!
Server Socket Instantiated
Client Socket Created
Client Socket Created
Client Socket Created
Client Sockets Instantiated
Server connected to clients
Finished writing. Continue reading...
Sent Finish Message 1
Computer #2
Computer is starting!
Server Socket Instantiated
Client Socket Created
Client Socket Created
Client Socket Created
Client Sockets Instantiated
Reading events
Server connected to clients
Finished writing. Continue reading...
Sent Finish Message 2
Computer #3: According to the log, this sent the finished message to controller
Computer is starting!
Server Socket Instantiated
Client Socket Created
Client Socket Created
Client Socket Created
Client Sockets Instantiated
Reading events
Server connected to clients
Finished writing. Continue reading...
Sent Finish Message 3
I've been struggling lately to find a way to deliver strings through a socket file. I'm planning to create a remote tool(client) to execute things based on the received message(server).
I've searched answers for my problem on google and i found some things and managed to understand things but I also got some problems (i'm new to programming, not yet in college).
I would appreciate any help in this matter
SocketService.java ---- class file = serverside
package socket;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;
public class ServiceSocket {
static ServerSocket myService;
static Socket thesocket;
static Thread socketThread;
public static boolean socketRunning;
public static DataInputStream socketMessage;
public static void initialise(String localhost, int portNumber ){
// make a server socket//////
try {
myService = new ServerSocket(portNumber);
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
//////////////////////////////
}
public static void deploySocket(){
socketThread = new Thread() {
public void run(){
// making connection
System.out.println("VVaiting for connection...");
try {
thesocket = myService.accept();
System.out.println("Connection made");
socketRunning = true;
} catch (IOException e) {
e.printStackTrace();
}
////////////////////////////////////
try {
StartBrain();
} catch (IOException e1) {
e1.printStackTrace();
}
if(socketRunning = false) {
try {
thesocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
socketThread.start();
}
public static String getSocketMessage() throws IOException {
try {
socketMessage = new DataInputStream(thesocket.getInputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
boolean looprunning = true;
String message = null;
System.out.println("entering loop");
do {
try {
while (socketMessage.readUTF() != null) {
message = socketMessage.readUTF();
looprunning = false;
}
} catch (EOFException e) {
}
}while(looprunning);
System.out.println("Message received from UTF: " + message);
System.out.println("loop exited vvith message");
if(message == null) {
message = "no message";
}
return message;
}
public static void StartBrain() throws IOException {
System.out.println("socket brain started");
String BrainMessage = getSocketMessage();
if(BrainMessage == "command") {
System.out.println("Command EXECUTED HAHA");
} else if(BrainMessage == "taskschedule") {
System.out.println("task scheduled");
} else {
System.out.println("no command received");
}
}
Main.java ----- class file = serverside
package main;
import socket.ServiceSocket;
public class Main {
public static void main(String[] args) {
ServiceSocket.initialise("localhost", 3535);
ServiceSocket.deploySocket();
}
}
}
Main.java = CLIENT
package mainPackage;
import java.io.*;
import java.net.*;
import java.util.concurrent.TimeUnit;
public class Main {
private static Socket clientSocket;
public static void sendMessage(String message) throws IOException, InterruptedException {
DataOutputStream dOut = new DataOutputStream(Main.clientSocket.getOutputStream());
dOut.writeUTF(message);
dOut.flush();
dOut.close();
}
public static void main(String[] args) throws Exception {
// String modifiedSentence;
clientSocket = new Socket("localhost", 3535);
System.out.println("Initializing");
sendMessage("command");
boolean running = true;
while(running) {
TimeUnit.SECONDS.sleep(3);
sendMessage("taskschedule");
}
clientSocket.close();
}
}
main problem
do {
try {
while (socketMessage.readUTF() != null) {
message = socketMessage.readUTF();
looprunning = false;
}
} catch (EOFException e) {
}
}while(looprunning);
it doesn't read the string/UTF
It does read it, here:
while (socketMessage.readUTF() != null) {
and then throws it away as you're not assigning the return-value to a variable, and then tries to read another one, here:
message = socketMessage.readUTF();
but the one (first) message you send is already gone.
You have problem in
while (socketMessage.readUTF() != null) {
message = socketMessage.readUTF();
looprunning = false;
}
First call to method readUTF() will block thread and read UTF string from socket, but you discard this value and try read string second time.
If you replace socketMessage.readUTF() != null with looprunning server will log this messages:
VVaiting for connection...
Connection made
socket brain started
entering loop
Message received from UTF: command
loop exited vvith message
no command received
P.S.
Command is not recognized because use compare objects (string is object) with ==, but you must use equals.
public static void StartBrain() throws IOException {
System.out.println("socket brain started");
String BrainMessage = getSocketMessage();
if (BrainMessage.equals("command")) {
System.out.println("Command EXECUTED HAHA");
} else if (BrainMessage.equals("taskschedule")) {
System.out.println("task scheduled");
} else {
System.out.println("no command received");
}
}
Server log:
VVaiting for connection...
Connection made
socket brain started
entering loop
Message received from UTF: command
loop exited vvith message
Command EXECUTED HAHA
Good day every one! So I have this android app which acts as a client and tries to connect to a java application on my PC that has a Bluetooth server component in it.
The issue I'm facing is that the connection only establishes when I don't have my PC in the paired devices list of my Nexus 5. In other words they only connect when they are paired. Therefore I've been forced to remove My PC from the list of Paired devices every time that I want to have a connection or else the connection fails.
I have used this Simple Android and Java Bluetooth Application for the base of the server side application:
import java.io.IOException;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
public class WaitThread implements Runnable{
public WaitThread() { }
#Override
public void run() {
waitForConnection();
}
/** Waiting for connection from devices */
private void waitForConnection() {
// retrieve the local Bluetooth device object
LocalDevice local = null;
StreamConnectionNotifier notifier;
StreamConnection connection = null;
// setup the server to listen for connection
try {
local = LocalDevice.getLocalDevice();
local.setDiscoverable(DiscoveryAgent.GIAC);
UUID uuid = new UUID("04c6032b00004000800000805f9b34fc", false);
System.out.println(uuid.toString());
String url = "btspp://localhost:" + uuid.toString() + ";name=RemoteBluetooth";
notifier = (StreamConnectionNotifier) Connector.open(url);
} catch (BluetoothStateException e) {
System.out.println("Bluetooth is not turned on.");
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
// waiting for connection
while(true) {
try {
System.out.println("waiting for connection...");
connection = notifier.acceptAndOpen();
Thread processThread = new Thread(new ProcessConnectionThread(connection));
processThread.start();
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}
}
and used the BluetoothChat from android sample projects for base of the client side:
import java.io.IOException;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
public class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
Handler mHandler;
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private static final UUID MY_UUID = UUID
.fromString("04c6032b-0000-4000-8000-00805f9b34fc");
public ConnectThread(BluetoothDevice device, Handler handler) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmpSocket = null;
mmDevice = device;
mHandler = handler;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
tmpSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Message msgException = new Message();
msgException.setTarget(mHandler);
msgException.what = Constants.DISCONNECTED_HANDLER;
msgException.sendToTarget();
}
mmSocket = tmpSocket;
}
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
Message msg1 = new Message(); // handler. we use it to know when de
// device has been connected or
// disconnected in the UI activity
msg1.setTarget(mHandler);
msg1.what = Constants.CONNECTING_HANDLER;
msg1.sendToTarget();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
// handler
Message msg2 = new Message();
msg2.setTarget(mHandler);
msg2.what = Constants.CONNECTED_HANDLER;
msg2.setTarget(mHandler);
msg2.sendToTarget();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
System.out.println("alex - NO connected");
Message msgException = new Message();
msgException.setTarget(mHandler);
msgException.what = Constants.DISCONNECTED_HANDLER;
msgException.sendToTarget();
try {
mmSocket.close();
} catch (IOException closeException) {
}
return;
}
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
public BluetoothSocket getBTSocket() {
return mmSocket;
}
}
I have a feeling this might be because of the UUID that I'm using. The UUIDs that worked for me were the followings:
04c6032b00004000800000805f9b34fc
0000110500001000800000805f9b34fb
I am using the similar UUIDs in both applications. Any Idea what might be causing this issue?
Strangely enough, today when I used a Bluetooth dongle instead of my own laptop's Bluetooth the problem got resolved. Therefore It was not an issue on behalf of the software component.
I'm new to java / object oriented language and wanted to get some help on the syntax.
I have a class defined in ConnectThread.java as
public class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
tmp = device.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
//manageConnectedSocket(mmSocket);
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
From here I tried to create a thread and connect this thread by writing this code in my connect method:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice targetdevice;
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0)
{
// Loop through paired devices
for (BluetoothDevice device : pairedDevices)
{
if (device.getName().equals("HC-06"))
targetdevice = device;
}
}
Thread writeThread = new Thread();
writeThread.ConnectThread(targetdevice);
I get the error in the last line and it says "The method ConnectThread(BluetoothDevice) is undefined for the type Thread"
I thought since ConnectThread is an extended class of Thread, I could use the methods under it. Is this not the case? What would be the right way to go about doing this?
Thanks!
Change your last two strings to:
Thread writeThread = new ConnectThread(targetdevice);
When you need to start your ConnectThread use start() method:
writeThread.start(); //If you need start run() method of ConnectThread.
i wrote a simple TCP-client class in Java. It is used to connect to a TCP-server written in Python and handle the incoming messages in a new thread. It looks like this:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
public class TCPTestClient {
private String mHost;
private int mPort;
private Socket mSocket;
private PrintWriter mWriter;
private BufferedReader mReader;
public TCPTestClient(String host, int port) {
mHost = host;
mPort = port;
}
public void connect() throws IOException {
if (mSocket == null || mSocket.isClosed()) {
mSocket = new Socket();
mSocket.connect(new InetSocketAddress(mHost, mPort), 5000);
mWriter = new PrintWriter(mSocket.getOutputStream());
mReader = new BufferedReader(new InputStreamReader(mSocket
.getInputStream()));
new Thread(new InputHandler(mReader, this)).start();
}
}
public void close() throws IOException {
if (mSocket != null && !mSocket.isClosed()) {
mSocket.close();
}
}
class InputHandler implements Runnable {
BufferedReader mReader;
TCPTestClient mClient;
public InputHandler(BufferedReader reader, TCPTestClient client) {
mReader = reader;
mClient = client;
}
public void run() {
String line = null;
try {
while ((line = mReader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The TCP-server simply prints "client connected" and "client disconnected" to stdout if a new client has connected or disconnected. This works great when running the TCPTestClient in a normal java-application: The connection is established when calling connect() and closed when calling close() and the waiting readLine() inside the InputHandler will fail because of a SocketException saying that the socket was closed (java.net.SocketException: Socket closed). This is the behaviour i expected.
But when i run this code on Android, the conection will not be closed: readLine() still blocks without throwing a SocketException and the server does not show the "client disconnected"-message.
Here is my activity:
import java.io.IOException;
import android.app.Activity;
import android.util.Log;
public class Foo extends Activity {
private TCPTestClient mClient;
private static final String TAG = "Foo";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.foo);
mClient = new TCPTestClient("192.168.1.2", 3456);
}
#Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
try {
mClient.close();
} catch (IOException e) {
Log.d(TAG, "Disconnect failed", e);
}
}
#Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
try {
mClient.connect();
} catch (IOException e) {
Log.d(TAG, "Connect failed", e);
}
}
}
So when the Activity is started/resumed, the connection will be established. And when the user clicks on the Back-Button, the connection should be closed. However, onPause() and close() is called, but the socket is not closed because the BufferedReader still blocks waiting for Input. A call like mReader.close() inside the close-method blocks, too.
Does anyone know how to fix this issue so that the connection will be closed successfully when the Activity is paused?
How have you verified that the client socket isn't closed?
The only reliable way to detect closed connections on the server side is to write data, and add heartbeats to the protocol.
Yes, pre 2.3 you have to use mSocket.shutdownInput() and mSocket.shutdownOutput() for it to throw the exception. But currently in 2.2.2, it doesn't work for me. :( Still finding a way to throw an exception.