Unfortunately I can't send a simple String message via UDP. The code is simple. I created a SendLocation class and I want send a location message with this. Everytime I try it, I've got the "can't send it" message. Any idea? Thanks a lot!
(messDelay, messCount, ip, port are EditTexts)
private class SendLocation extends Thread {
private String message = "";
private volatile boolean flag = true;
public SendLocation(String message) {
this.message = message;
}
#Override
public void run() {
while (flag) {
try {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(Server.this, message, Toast.LENGTH_SHORT).show();
}
});
byte[] data = message.getBytes();
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(ip.getText().toString()),
Integer.valueOf(port.getText().toString()));
for (int i = 0; i < Integer.valueOf(messCount.getText().toString()); i++) {
socket.send(packet);
Thread.sleep(Integer.valueOf(messDelay.getText().toString()));
}
socket.close();
} catch (Exception e) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(Server.this, "Can't send it", Toast.LENGTH_SHORT).show();
}
});
}
flag = false;
}
}
}
Related
I am building an application that starts a Connection via a Thread but when i initialize the Connection the Application doesn't connect and stops (it continues to work but it does nothing).
1 week ago it did work without any troubles, but when i updated Android Studio it started causing me this problem.
This is the abstract class of the Connection:
public abstract class Connection implements Runnable{
private Socket socket;
private PrintWriter writer;
private BufferedReader reader;
private Semaphore semaphore;
private ArrayList<String> messageQueue;
private Thread connection;
//private String state; // CONNECTED,RUNNING,STOPPED,RESTARTED,CLOSED
Connection(InetAddress address, int port) {
try {
socket = new Socket(address,port);
onConnectionEstablished(socket);
writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
semaphore = new Semaphore(1);
messageQueue = new ArrayList<>();
} catch (Exception e) {
close();
}
}
#Override
public void run() {
connection = Thread.currentThread();
while(!connection.isInterrupted()){
this.read();
}
}
// Checks if connection is established
boolean isConnectionEstablished(){
return socket != null && !socket.isClosed();
}
public abstract Socket onConnectionEstablished(Socket socket);
// Restarts the connection
public abstract void onConnectionClose();
// Launched when message is received
public abstract String onMessageReceived(String message);
// Launched when message is posted
public abstract String onMessagePosted(String message);
// Launched when message is sent
public abstract String onMessageSent(String message);
// Post message
public void postMessage(String message){
messageQueue.add(message);
sendMessage();
}
// Send Message
private void sendMessage() {
final String message = messageQueue.get(0);
onMessagePosted(message);
new Thread(new Runnable() {
#Override
public void run() {
try {
semaphore.acquire();
System.out.println(Colors.color("[*] Sending: \'"+message+"\' [*]","blue"));
writer.print(message);
writer.flush();
messageQueue.remove(0);
semaphore.release();
} catch (Exception e) {
close();
}
}
}).start();
onMessageSent(message);
}
// Read messages
private void read(){
try {
String message = reader.readLine();
if(message != null && message.length() > 0)
onMessageReceived(message);
else
throw new Exception();
} catch (Exception e) {
close();
}
}
// Close the connection
private void close(){
try{
connection.interrupt();
this.writer.close();
this.reader.close();
this.socket.close();
}catch(Exception e){
System.out.println(Colors.color("[X] Error while closing [X]","red"));
}
onConnectionClose();
}
// Restart the connection
void restart(){
new Thread(new Runnable() {
#Override
public void run() {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
System.out.println(Colors.color("[X] Error while restarting [X]","red"));
}
new Thread(new ConnectionInitializer()).start();
}
}).start();
}
}
While doing some debugging i found out that it apparently blocks when the socket is instantiated.
We have an main activity with a Text View which is requested to auto-retrieve data from TCP server in LAN.
We enabled AsyncTask in updateData() to call Connect to call Handler to update TextView named mTvVoc, and refresh connection by beginConnect().
The problem is the mTvVoc is not updated, it seems the AsyncTask does not function as expected?
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
updateData();
}
public void updateData(final String order) {
Connect(HOST, PORT, order);
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
System.out.println("get data from order--->" + order);
beginConnect(HOST, PORT, order);
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}.execute();
}
public String Connect(final String HOST, final int PORT, final String OderType) {
new Thread(new Runnable() {
#Override
public void run() {
try {
socket = new Socket(HOST, PORT);
bufferedInputStream = new BufferedInputStream(socket.getInputStream());
System.out.println("bufferedInputStream--->" + bufferedInputStream);
printWriter = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
if (socket.isConnected()) {
if (!socket.isOutputShutdown()) {
printWriter.println(Integer.toHexString(Integer
.parseInt(OderType)));
}
}
while (true) {
if (!socket.isClosed() && socket.isConnected() && !socket.isInputShutdown()) {
int temp = 0;
byte[] buf = new byte[1024];
while ((temp = bufferedInputStream.read(buf)) != -1) {
isConn(socket);
Log.d("Data received", new String(buf, 0, temp));
acceptinfo = new String(buf, 0, temp);
System.out.println("Data received====》" + acceptinfo);
Message message = new Message();
message.what = 1;
message.obj = acceptinfo;
handler.sendMessage(message);
}
}
}
} catch (UnknownHostException e) {
System.out.println("UnknownHostException-->connection failed");
stopConnect();
e.printStackTrace();
} catch (IOException e) {
System.out.println("IOException-->connection failed");
stopConnect();
e.printStackTrace();
}
}
}).start();
return acceptinfo;
}
public String beginConnect(final String HOST, final int PORT, final String OderType) {
new Thread(new Runnable() {
#Override
public void run() {
try {
socket = new Socket(HOST, PORT);
bufferedInputStream = new BufferedInputStream(socket.getInputStream());
System.out.println("bufferedInputStream--->" + bufferedInputStream);
printWriter = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
if (socket.isConnected()) {
if (!socket.isOutputShutdown()) {
printWriter.println(Integer.toHexString(Integer.parseInt(OderType)));
}
}
} catch (UnknownHostException e) {
System.out.println("UnknownHostException-->connection failed");
stopConnect();
e.printStackTrace();
} catch (IOException e) {
System.out.println("IOException-->connection failed");
stopConnect();
e.printStackTrace();
}
}
}).start();
return acceptinfo;
}
public Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.i("message", msg.obj.toString());
if (msg.what == 0) {
mIvContent.setImageResource(R.drawable.wangluo_gray);
Toast.makeText(MainActivity.this, "Server connection failed", Toast.LENGTH_SHORT).show();
reGetData();
}
if (msg.what == 1) {
String info = msg.obj.toString();
if (info.length() != 18) {
mIvContent.setImageResource(R.drawable.wangluo_gray);
System.out.println("data verification failed");
reGetData();
return;
}
String iszeroupString = info.substring(1, 3);
String temperature = Integer.toString(Integer.parseInt(info.substring(3, 5), 16));
String vocValue = Integer.toString(Integer.parseInt(info.substring(7, 9), 16));
mTvVoc.setText(getVOC((Integer.valueOf(vocValue ) / 100.00)));
}
}
}
You cannot directly communicate from background thread to UI thread to
update any UI components.
Use this in your background thread to update textview from AsyncTask.
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Log.d("UI thread", "I am the UI thread");
// update your text here
}
});
To update on UI, you need to run the codes in UIThread. See code below and put in your handler:
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.i("message", msg.obj.toString());
if (msg.what == 0) {
mIvContent.setImageResource(R.drawable.wangluo_gray);
Toast.makeText(MainActivity.this, "Server connection failed", Toast.LENGTH_SHORT).show();
reGetData();
}
if (msg.what == 1) {
String info = msg.obj.toString();
if (info.length() != 18) {
mIvContent.setImageResource(R.drawable.wangluo_gray);
System.out.println("data verification failed");
reGetData();
return;
}
String iszeroupString = info.substring(1, 3);
String temperature = Integer.toString(Integer.parseInt(info.substring(3, 5), 16));
String vocValue = Integer.toString(Integer.parseInt(info.substring(7, 9), 16));
mTvVoc.setText(getVOC((Integer.valueOf(vocValue ) / 100.00)));
}
}
});
Pretty bad to code that handler to update the gui. Do away with it as AsyncTask provides already the functionality to do so.
You should have looked better at the many examples.
Use publishProgress() and onProgressUpdate() to update a progress bar and/or other gui elements.
And do not wrap your code in a thread if it has to be executed in doInBackground().
why UDP Android just once send [Please Help]
name class MainActivity
public class MainActivity extends Activity implements
android.view.View.OnClickListener {
public static final String SERVERIP = "192.168.5.255";
public static final int SERVERPORT = 4444;
public TextView text1;
public EditText input;
public Button btn;
public boolean start;
public Handler Handler;
conntection with pc
this method on create
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text1 = (TextView) findViewById(R.id.textView1);
input = (EditText) findViewById(R.id.editText1);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(this);
start = false;
new Thread(new Server()).start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
new Thread(new Client()).start();
Handler = new Handler() {
#Override
public void handleMessage(Message msg) {
String text = (String) msg.obj;
text1.append(text);
}
};
}
this class Client
#SuppressLint("NewApi")
public class Client implements Runnable {
#Override
public void run() {
while (start == false) {
}
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
updatetrack("Client: Start connecting\n");
DatagramSocket socket = new DatagramSocket();
byte[] buf;
if (!input.getText().toString().isEmpty()) {
buf = input.getText().toString().getBytes();
} else {
buf = ("Default message").getBytes();
}
DatagramPacket packet = new DatagramPacket(buf, buf.length,
serverAddr, SERVERPORT);
updatetrack("Client: Sending ‘" + new String(buf) + "’\n");
socket.send(packet);
updatetrack("Client: Message sent\n");
updatetrack("Client: Succeed!\n");
} catch (Exception e) {
updatetrack("Client: Error!\n");
}
}
}
this class Client
public class Server implements Runnable {
#Override
public void run() {
while (start = false) {
try {
InetAddress serverAddress = InetAddress.getByName(SERVERIP);
updatetrack("nServer: Start connectingn");
DatagramSocket socket = new DatagramSocket(SERVERPORT,
serverAddress);
byte[] buffer = new byte[17];
DatagramPacket packet = new DatagramPacket(buffer,
buffer.length);
updatetrack("Server: Receivingn");
socket.receive(packet);
updatetrack("Server: Message received:"
+ new String(packet.getData()) + "'n");
updatetrack("Server : Succed!n");
} catch (Exception e) {
updatetrack("Server: Error!n" + e.getMessage());
}
}
}
}
public void updatetrack(String s) {
Message msg = new Message();
String textTochange = s;
msg.obj = textTochange;
Handler.sendMessage(msg);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (v.getId() == R.id.button1)
start = true;
}
}
if i make my class server with
while (true){
application is error
help me please ? why just once send message Thanks before
For Client class, you have nothing in the loop:
while (start == false) {
}
And then outside of it, you call send only once -- that is why it is sending only once.
socket.send(packet);
If you want to call send continuously, then one way to do is to keep it in a loop. Of course, you would need to terminate the loop once the task is done but that would be driven by your application logic.
I have an app which works with UDP packets. So I want to send and receive UDP packets at the same time in the same app. Is it real? Now it works perfectly, but separately.
Code snippet:
UDP Server:
public class UDPServer {
DatagramPacket packet;
DatagramSocket socket;
static int port = 11111;
private boolean isRun = false;
private String message = "";
private int broadcastInterval;
private Context context;
public boolean IsRunUDPServer(){
return isRun;
}
public void StopBroadcasting(){
isRun = false;
}
public void StartBroadcasting(String message, int broadcastInterval){
isRun = true;
this.message = message;
this.broadcastInterval = broadcastInterval;
new Thread(runner).start();
}
Runnable runner = new Runnable() {
public void run() {
while(isRun){
try {
//Sending(message);
SendBroadcastMessageOverWiFi(message);
Thread.sleep(broadcastInterval);
Log.e("SendBroadcastMessageOverWiFi", message);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
}
}
if(socket!=null){
socket.disconnect();
socket.close();
}
}
};
public UDPServer(Context context) {
this.context=context;
}
private InetAddress getBroadcastAddress() throws IOException {
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
DhcpInfo dhcp = wifi.getDhcpInfo();
// handle null somehow
if(dhcp==null){ return null; }
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);
}
private void SendBroadcastMessageOverWiFi(String message) throws IOException{
InetAddress addr = getBroadcastAddress();
if(addr!=null){
if(socket==null){
socket = new DatagramSocket(port);
socket.setBroadcast(true);
}
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length,
addr, port);
socket.send(packet);
}
}}
UDP Client:
public class UDPClient {
MulticastSocket socket;
InetAddress groupAddress;
DatagramPacket packet;
byte[] buffer;
private static final int UDP_SERVER_PORT = 11111;
private static final int MAX_UDP_DATAGRAM_LEN = 32768;
public interface OnReceiveDataListener{
public abstract void onReceiveData(String data);
}
private OnReceiveDataListener ReceiveDataListener = null;
public void setReceiveDataListener(OnReceiveDataListener ReceiveDataListener) {
this.ReceiveDataListener = ReceiveDataListener;
}
public OnReceiveDataListener getReceiveDataListener() {
return ReceiveDataListener;
}
private boolean isRun = false;
private Thread broadcastReceiver;
public void StopReceiving(){
isRun = false;
}
public void StartReceiving(){
isRun = true;
buffer = new byte[4096];
broadcastReceiver = new Thread(runner);
broadcastReceiver.start();
}
Runnable runner = new Runnable() {
#Override
public void run() {
while(isRun){
String lText;
packet = new DatagramPacket(buffer, buffer.length);
DatagramSocket ds = null;
try {
ds = new DatagramSocket(UDP_SERVER_PORT);
ds.receive(packet);
lText = new String(packet.getData(), 0, packet.getLength());
Log.i("UDP packet received", lText+" "+packet.getLength()+" "+packet.getData().length);
if(getReceiveDataListener()!=null)
getReceiveDataListener().onReceiveData(lText);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
}
}
};}
If I start server, the client won't be able receive udp packets.
Please help me. Thank you.
Only one socket (in one process) can bind to a given UDP port at one time. It is not permitted to have two sockets bind to the same UDP port number.
In most cases, there is no reason to have the client bound to a specific port. Instead, specify port 0 (INADDR_ANY) and the system will assign an unused dynamic port.
I use the following code to receive the data using UDP. When I click the back button my screen visual is closed and it shows the home screen. But a thread is working in the background (it receives the data from the UDP server). When I close the application I also need to stop the thread. How to stop a thread?
public void onClick(View view) {
port=Integer.parseInt(etd_port.getText().toString());
etd_port.setCursorVisible(false);
Thread fst = new Thread(new Server());
fst.start();
}
public class Server implements Runnable {
private String tagid="",roomid="";
public final int SERVERPORT = port;
private DatagramSocket ds;
private String recdata;
#Override
public void run() {
int buffer_size = 1024;
byte buffer[] = new byte[buffer_size];
try {
ds = new DatagramSocket(SERVERPORT);
while (true) {
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
ds.receive(p);
Log.d("MY UDP ","After Receive");
recdata=new String(p.getData(),0,p.getLength());
Log.d("Receive data ",recdata);
}
} catch(Exception e){
Log.e("MY UDP ", " Error", e);
}
}
}
......
#Override
protected void onStop() {
finish();
fst.stop();
super.onStop();
}
You have to change while condition:
class Server implements Runnable {
private boolean running;
public void run() {
running = true;
while (running) {
// do stuff here
}
}
public stop() {
running = false
}
}
protected void onStop() {
fst.stop()
}