Async socket connection, Client GUI Hangs When Server is Disconnected TCP Communication - android

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.

Related

The socket stop t Socket.accept() in Android for TCP Server

I try to create a Simple TCP Server on Android phone and waiting for client.
I only want to implement the connection between TCPServer and Client , it doesn't need to transmit any data.
I have the another application for client , It use to connect to this TCPServer.
The code of TCPServerthread is like the following.
private class TCPServerThread implements Runnable
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
ServerSocket serverSocket = new ServerSocket(PORT);
//while loop
while (true) {
Log.i(TAG, "TCPServerThread...while loop");
try {
Socket socket = serverSocket.accept();
Log.i(TAG, "TCPServerThread...socket.getInetAddress() = " + socket.getInetAddress());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
Log.i(TAG, "First IOException");
}
}
//while loop end
} catch (Exception e) {
// TODO: handle exception
//e.printStackTrace();
Log.i(TAG, "Second IOException");
}
}
}
But it seems stop at Socket socket = serverSocket.accept(); and doesn't show the log of TCPServerThread...socket.getInetAddress() = when the client try to connect to this Server.
DO I missing something for TCPServer ?
Is it mean the client doesn't connect to the Server when the code stop at Socket socket = serverSocket.accept(); ??
----------------------------EDIT----------------------------------------
Update the process.
The Server(Android Phone) open the WiFi-Hot-Spot, it also open the TCP-Server like the above code.
After Client connect to WiFi-Hot-Spot , the Client and the Server are in the same network.
The Client will get a IP address of gateway, and the Client try to connect to this IP address of gateway by TCP.
So the connection port and Server address seems correct for Client.
Your code is correct, but it seems that no one is connecting to your TCPserver.
To avoid this blocking situation on
Socket socket = serverSocket.accept();
you have to set the timeout option for your socket when you declare it
serverSocket.setSoTimeout(mTime);
;)

Android send udp broadcast silently fails

I want to implement service discovery by using the network's broadcast address. I am sniffing packets with WireShark to confirm that my UDP packets are not being sent. The network code is not being run on the UI thread. The DatagramSocket.send call returns with no exception thrown, but nothing is seen by other programs including WireShark. I have verified that the address returned by getWifiBroadcastAddress actually is the broadcast address of my network.
I have verified that the network supports broadcast by writing a C# program, run on another machine, and WireShark is detecting broadcast packets from this program.
Here is my Android Java code:
try {
DatagramSocket socket = new DatagramSocket(Protocol.INQUIRY_PORT);
socket.setBroadcast(true);
InetAddress broadcastAddr = getWifiBroadcastAddress();
byte[] data = new byte[10];
for(int i = 0; i < data.length; i++) {
data[i] = (byte) i;
}
DatagramPacket packet = new DatagramPacket(data, data.length,
broadcastAddr, Protocol.INQUIRY_PORT);
while(true) {
// Loops indefinitely, no errors/exceptions
socket.send(packet);
try {
Thread.sleep(5000);
} catch(InterruptedException ie) {
break;
}
}
} catch(IOException ioe) {
// Not logged
Log.d("Broadcast", "Error sending inquiry.");
}
The getWifiBroadcastAddress() method is as seen here: https://lab.dyne.org/AndroidUDPBroadcast
Does anyone know why this would fail silently? Like I said my C# program running on another box is working just fine, doing the same thing, sending the same data every 5s, and WireShark sees those packets, but nothing from the Android phone.
The following works for me, where I can broadcast a particular string value to a specified port (in your case Protocol.INQUIRY_PORT) on the other end(s), and all of the devices on the local subnet that are monitoring UDP on that port can recognize that string value, and accordingly can respond. I am broadcasting from the main thread, but listening for responses in an async task.
public void sendBroadcast(String messageStr) {
// Hack Prevent crash (sending should be done using an async task)
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
byte[] sendData = messageStr.getBytes();
try {
sendSocket = new DatagramSocket(null);
sendSocket.setReuseAddress(true);
//sendSocket.bind(new InetSocketAddress(Protocol.INQUIRY_PORT));
sendSocket.setBroadcast(true);
//Broadcast to all IP addresses on subnet
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("255.255.255.255"), Protocol.INQUIRY_PORT);
sendSocket.send(sendPacket);
System.out.println(getClass().getName() + ">>> Request packet sent to: 255.255.255.255 (DEFAULT)");
} catch (Exception e) {
}
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
}
}
Following is the corresponding UDP response listener code inside an async task class:
protected String doInBackground(String... params) {
serverIP = "";
try {
//Keep a socket open to listen to all the UDP trafic that is destined for this port
InetAddress myHostAddr = InetAddress.getByName("0.0.0.0");
rcvSocket = new DatagramSocket(null);
rcvSocket.setReuseAddress(true);
rcvSocket.bind(new InetSocketAddress("0.0.0.0",Protocol.INQUIRY_PORT));
rcvSocket.setBroadcast(true);
while (true) {
Log.i("VIS","Ready to receive broadcast packets!");
//Receive a packet
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
rcvSocket.receive(packet);
//Packet received
serverIP = packet.getAddress().getHostAddress();
Log.i("VIS", "Packet received from: " + serverIP);
String data = new String(packet.getData()).trim();
Log.i("VIS", "Packet received; data: " + data);
if (!data.equals("") && !data.equals(myInquiryString)) {
//break while loop and return IP address of server
break;
}
}
} catch (IOException ex) {
Log.i("VIS", "ServerDiscovery" + ex.getMessage());
}
return serverIP;
}

connection between server running perl skript and android

I am trying to send data from my Android phone to my home-server by using sockets. My server runs Linux so I used Perl to code the script for my server. The connection works fine and I can send data to my client running on the phone.
Problem is, when I send something (first try was a simple string) to the server, I don't receive anything at the servers side. Everything works fine if I use telnet to send a string to the server.
I am sitting here for some time now and I looked if there was a similar question to mine and could not find any in which the problem is discussed for Android to Perl-script. Here is my code for the Android app:
try {
Socket socket = new Socket("192.168.178.22", 22222);
Statusinformation("connection with server succeed");
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Statusinformation(input.readLine());
OutputStream outstream =socket.getOutputStream();
PrintWriter out = new PrintWriter(outstream);
out.println("This is a test message from client on phone!\n");
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
Statusinformation("connection unsucsessfull");
e.printStackTrace();
}
on my phone I receive this if i execute the above code:
connection with server succeed!
and on the server side I'm using this code to receive the string from socket clients:
use IO::Socket;
my $server = IO::Socket::INET -> new(
Proto => 'tcp',
LocalPort => 22222,
Listen => SOMAXCONN,
);
print "Server started..\n";
while (1) {
next unless my $conect = $server -> accept();
my $childconection = fork;
if ($childconection == 0) {
handle_connection($conect);
}
}
sub handle_connection
{
my $sock = shift;
my $client_message="";
my $client_addr = $sock -> peerhost;
print "connection: $client_addr connected\n";
print $sock "hi $client_addr, you are connected!\n";
while (1) {
open (Tempfile, '>>tempfile.txt');
while ($client_message = <$sock>) {
print Tempfile $client_message;
print $client_message;
}
close (Tempfile);
}
close($sock);
exit(0);
}
ok now I am a little ashamed.
I solved the problem by adding:
out.flush();
the flush() method assures that all pending data is send to the target and flushs the target.

Handling all clients in a java Socket Server

I have a server and i am trying to send to all clients a specific input(string). My code is here:
serverSocket = new ServerSocket(SERVERPORT);
while (true)
{
// listen for incoming clients
Socket client = serverSocket.accept();
mClients.add(client);
boolean finished = false;
try
{
for (int i=0; i<mClients.size(); i++)
{
Socket well = mClients.get(i);
DataInputStream in = new DataInputStream(well.getInputStream());
PrintStream out = new PrintStream(well.getOutputStream());
// Print a message:
System.out.println("Client from : " + client.getInetAddress() + " port " + client.getPort());
// now get the input from the socket...
while(!finished)
{
String st = in.readLine();
// Send the same back to client
out.println(st);
// Write it to the screen as well
System.out.println(st);
// If the input was "quit" then exit...
if (st.equals("quit")) { finished = true; System.out.println("Thread exiting..."); }
}
}
As it seems i am doing something wrong. Anyway i am trying to store all the connected sockets to a vector and then send them the string received by one of them. Is this the right approach?
In the first while(true) statement, only listen for incoming connections and then create a separate thread to handle that client connection.
From there, you could add each outPutStream you create, within each thread, into an global ArrayList. Loop through the arrayList(create a method for this with a String Parameter) and write whatever message you want to within said method.
Check out this Oracle Tutorial on Socket Communication for help

android TCP client unable to display data sent from C Server via wi-fi

I'm kinda new to android socket programming. My android program simply connects to a server (written in c,executed in the console) and must display the content being sent from the server (something like "hi client"). I have textview's for displaying whether the connection is being established or not and another edittext for sending the client's message to the server. The system is connected via Wi-fi. The server is able to recieve messages from my android client but android client is not displaying the message sent by the server. The code snippet for the reading from server part is:
private TextView MsgFromServer; //defination
// here is the code for the connection and starting new thread etc
final BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
handler.post(new Runnable() {
#Override
public void run() {
try {
while((line=in.readLine())!=null){
MsgFromServer.append(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Also I tried doing something like this:
final BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
line=in.readLine().toString(); //string type
handler.post(new Runnable() {
#Override
public void run() {
MsgFromServer.setText(line);
}
}
both approaches are not working for me.The message I send from the client to the server reaches there properly whereas the other direction communication is not happening. Also I've tested my C server with a simple C client and the message passing is happening smoothly.
How does the client behave? Is it waiting at in.readLine() ?
Be sure the server sends "Hi client\n" (with the lineend).
in.readLines() only returns when a lineend \n is found.
Is the new Runnable running? If you change the code
a little to
try {
MsgFromServer.append("going to read a line..");
while((line=in.readLine())!=null){
MsgFromServer.append(line);
}
then do you see that?

Categories

Resources