Hi every one i am developing a chat application in android for that i have developed a sever in java to route messages. The system works in such a way that after connecting to server the clients send its id to server. Now the problem i am having is that some times the server receives the id from client and most of the time the server don't receive the id. Please help me i have no idea why is it behaving like this
the code for server
System.out.println("server starting at port: "+ portnumber);
serverSocket = new ServerSocket(portnumber);
while(true){
System.out.println("waiting for client# "+ clientno);
//connecting to client's call
Socket socket = serverSocket.accept();
System.out.println("Client# "+ clientno +" connected!!!");
//recieving clients name
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
int idOfClient = br.read();
System.out.println("" + idOfClient);
}
and the code for client
public class MainActivity extends Activity {
private static final String TAG = "ChatActivity";
private static final String hostname="192.168.0.100";
private static final int portnumber=60123;
private ChatArrayAdapter chatArrayAdapter;
private ListView listView;
private EditText chatText;
private Button buttonSend;
private boolean side = false;
private BufferedWriter bw;
private BufferedReader br;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonSend = (Button) findViewById(R.id.send);
listView = (ListView) findViewById(R.id.msgview);
chatArrayAdapter = new ChatArrayAdapter(getApplicationContext(), R.layout.right);
listView.setAdapter(chatArrayAdapter);
chatText = (EditText) findViewById(R.id.msg);
chatText.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
try {
return sendChatMessage();
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
});
Thread thread=new Thread(){
public void run() {
try {
chatArrayAdapter.add(new ChatMessage(!side, "Connecting to server"));
final Socket socket = new Socket(hostname, portnumber);
chatArrayAdapter.add(new ChatMessage(!side, "Connected to server"));
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write(2);
bw.newLine();
bw.flush();
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true) {
//if (br.ready()) {
//chatText.setText(br.readLine());
chatArrayAdapter.add(new ChatMessage(!side, br.readLine()));
//}
}
} catch (Exception e) {
}
}
};
thread.start();
buttonSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
try{
sendChatMessage();
}
catch(Exception e){
}
}
});
listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
listView.setAdapter(chatArrayAdapter);
//to scroll the list view to bottom on data change
chatArrayAdapter.registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged() {
super.onChanged();
listView.setSelection(chatArrayAdapter.getCount() - 1);
}
});
}
private boolean sendChatMessage() throws IOException {
String msg=chatText.getText().toString();
try {
bw.write(msg);
bw.newLine();
bw.flush();
chatArrayAdapter.add(new ChatMessage(side, msg));
}
catch(Exception e){
chatArrayAdapter.add(new ChatMessage(side,"Message not sent"));
}
chatText.setText("");
return true;
}
}
Try closing the bufferedReader after the print like this
int idOfClient=br.read();
System.out.println(""+idOfClient);
br.close();
Related
I am trying to make a simple java android app
I want to send an order from my computer (client) to my android app (server) the the mobile (server) must send the return back to the client (computer)
Client (computer)
public class Main {
public static void main(String[] args) {
Scanner sx = new Scanner(System.in);
String ln = sx.next();
try {
Socket s = new Socket("192.168.2.2", 4040);
s.setSoTimeout(4000);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(ln);
dos.flush();
s.close();
System.out.println("Done....");
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
Server (android app)
public class MainActivity extends Activity {
EditText portfield, ipfield;
LinearLayout player;
SharedPreferences sp;
SharedPreferences.Editor ed;
String myip, myport;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
player = (LinearLayout) findViewById(R.id.player);
portfield = (EditText) findViewById(R.id.portfield);
ipfield = (EditText) findViewById(R.id.ipfield);
sp = getSharedPreferences("okayawalas2423", MODE_PRIVATE);
ed = sp.edit();
myport = sp.getString("myport", null);
myip = sp.getString("myip", null);
runit();
}
public void runit() {
if (myport != null && myip != null) {
final String myport;
final String myip;
startspy();
}
}
public void startspy() {
player.removeAllViews();
Thread th = new Thread(new Runnable() {
public void run() {
eim();
}
});
th.start();
}
public void eim() {
try {
ServerSocket server = new ServerSocket(Integer.parseInt(myport));
say("Server Connected Successfully .... ");
while (true) {
Socket skt = server.accept();
say("The Server Request Has Been Accepted .... ");
DataInputStream dis = new DataInputStream(skt.getInputStream());
String purein = dis.readUTF();
dsay("Data Has Been Sent Right Now To /// and it contains : \n [[[ " + dis.readUTF() + " ]]]");
DataOutputStream dos = new DataOutputStream(skt.getOutputStream());
String outword = doit(purein);
dos.writeUTF(outword);
dos.flush();
dis.close();
dos.close();
skt.close();
}
} catch (Exception e) {
TextView tz = new TextView(this);
tz.setText(e.toString());
player.setGravity(Gravity.CENTER);
player.addView(tz);
}
}
public void stt(View v) {
if (portfield.getText().toString().equals("") || ipfield.getText().toString().equals("")) {
Toast.makeText(this, "Insert All Data !!", Toast.LENGTH_LONG).show();
} else {
ed.putString("myport", portfield.getText().toString());
ed.putString("myip", ipfield.getText().toString());
ed.commit();
startspy();
}
}
public String doit(String p) {
String funRes = "none";
funRes = p;
return funRes;
}
public void say(String s) {
TextView tz = new TextView(this);
tz.setText(s);
player.setGravity(Gravity.CENTER);
player.addView(tz);
}
public void dsay(String s) {
Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
}
}
I type the message on the computer (client) when I press ENTER, I get the "Done..." but the android app gets down!!
I'm attempting to use my android phone as a keyboard for my PC.
This is done over a local WiFi connection using sockets to create the client/server connection.
I'm using a textwatcher to pick up the change in characters in an editText and then sending those over to the server which then uses a robot class to write that onto the PC. This is all using a Softkeyboard on the android phone.
The issue is that when writing in editText only one character gets sent. and picked up by the server.
e.g. I type on the android phone "a" and the respective keypress will be simulated on the server. If I then type another character it does not read that character but if I delete the "a" and then type another character it will send that character.
Below is the Client side of the code, the Android application.
public class MainActivity extends AppCompatActivity implements View.OnKeyListener {
private final static int portNumber = ****;
private final static String hostName = "192.168.0.8";
private final static String cTest = "Connection Test";
Socket socket = null;
private static String TAG = "test";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread() {
#Override
public void run() {
try {
Log.i(cTest, "attempting to connect");
socket = new Socket(hostName, portNumber);
Log.i(cTest, "Connected");
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getBaseContext(), "Connected Successfully", Toast.LENGTH_SHORT).show();
}
});
EditText editText = (EditText)findViewById(R.id.editText);
editText.addTextChangedListener(editTextWatcher);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e(cTest, e.getMessage());
}
}
}.start();
}
private TextWatcher editTextWatcher = new TextWatcher() {
private void sendTextToServer(String send) {
BufferedWriter bw = null;
String textChange = send;
try {
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write(textChange);
bw.newLine();
bw.flush();
} catch (IOException e) {
}
}
public void afterTextChanged(Editable s)
{
}
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
public void onTextChanged(CharSequence s, int start, int before, int count)
{
Log.d(TAG, s + " Character Read");
String test = s.toString();
this.sendTextToServer(test);
}
};
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
return false;
}
}
The following code is the server side code which is being done in eclipse.
public class ListenServerMain {
private static boolean ifConnected = true;
private final static int portNumber = ****;
public static String readIn;
private static Socket client = null;
private static ServerSocket server = null;
private static BufferedReader in = null;
private static Robot robot = null;
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
robot = new Robot();
server = new ServerSocket(portNumber);
System.out.println("Listening on port :****");
client = server.accept(); //loops until a client server connection is established
System.out.println("Client connected");
//Receive a message from the client
BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
while(ifConnected)
{
readIn = in.readLine(); //reads the input received
if(readIn.equalsIgnoreCase("A"))
{
robot.keyPress(KeyEvent.VK_A);
robot.keyRelease(KeyEvent.VK_A);
}
if(readIn.equalsIgnoreCase("B"))
{
robot.keyPress(KeyEvent.VK_B);
robot.keyRelease(KeyEvent.VK_B);
}
if(readIn.equalsIgnoreCase("C"))
{
robot.keyPress(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_C);
}
if(readIn.equalsIgnoreCase("BS"))
{
robot.keyPress(KeyEvent.VK_DELETE);
robot.keyRelease(KeyEvent.VK_DELETE);
}
}
System.out.println("Unable to read user Input"); //if it can't read the input from the Client
System.exit(-1); //system exits
System.out.println("Server Ended");
System.exit(-1);
}
catch (IOException e) {
System.out.println("Can't open the Socket");
System.exit(-1);
}
catch (AWTException e) {
System.out.println("Unable to create Robot");
System.exit(-1);
}
}
}
Is there any way in which I can successfully read and send each character entered in the editText field?
If any further clarification about this is necessary let me know.
Thanks
On the MainActivity.java I have a method that connect with a server:
private byte[] Get(String urlIn)
{
URL url = null;
String urlStr = urlIn;
if (urlIn!=null)
urlStr=urlIn;
try
{
url = new URL(urlStr);
} catch (MalformedURLException e)
{
e.printStackTrace();
return null;
}
HttpURLConnection urlConnection = null;
try
{
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
byte[] buf=new byte[10*1024];
int szRead = in.read(buf);
byte[] bufOut;
if (szRead==10*1024)
{
throw new AndroidRuntimeException("the returned data is bigger than 10*1024.. we don't handle it..");
}
else
{
bufOut = Arrays.copyOf(buf, szRead);
}
return bufOut;
}
catch (IOException e)
{
e.printStackTrace();
return null;
}
finally
{
if (urlConnection!=null)
urlConnection.disconnect();
}
}
I'm calling this method from onTouchEvent():
#Override
public boolean onTouchEvent(MotionEvent event)
{
float eventX = event.getX();
float eventY = event.getY();
float lastdownx = 0;
float lastdowny = 0;
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
path.moveTo(eventX, eventY);
circlePath.addCircle(eventX, eventY, 50, Path.Direction.CW);
lastdownx = eventX;
lastdowny = eventY;
Thread t = new Thread(new Runnable()
{
#Override
public void run()
{
byte[] response = null;
if (is_start == true)
{
response = Get("http://10.0.0.2:8098/?cmd=start");
is_start = false;
}
else
{
response = Get("http://10.0.0.2:8098/?cmd=stop");
is_start = true;
}
if (response!=null)
{
String a = null;
try
{
a = new String(response,"UTF-8");
textforthespeacch = a;
MainActivity.currentActivity.initTTS();
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
Logger.getLogger("MainActivity(inside thread)").info(a);
}
}
});
t.start();
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(eventX, eventY);
break;
case MotionEvent.ACTION_UP:
circlePath.reset();
break;
default:
return false;
}
invalidate();
return true;
}
So now i'm connecting all the time to 10.0.0.2:8098
But that's when i connect my android device on my network on my pc room.
But if i move to the living room and connect to the network there a differenet network with another pc the pc ip is differenet in this case: 10.0.0.3:8099
So i added a button click event to the MainActivity.java:
public class MainActivity extends ActionBarActivity
{
private static final int MY_DATA_CHECK_CODE = 0;
public static MainActivity currentActivity;
TextToSpeech mTts;
private String targetURL;
private String urlParameters;
private Button btnClick;
private String clicking = "clicked";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addListenerOnButton();
currentActivity = this;
initTTS();
}
public void addListenerOnButton() {
btnClick = (Button) findViewById(R.id.checkipbutton);
btnClick.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
}
});
}
Inside the button click event I want to check after connected to the network with a wifi if the pc ip is 10.0.0.3:8099 or 10.0.0.2:8098
I need that it will try to connect to this servers and if success then to set to a global variable global string the ip.
I added a global variable: string ipaddress
Now i use static address in my code but i need to check which ip address is correct and then to set this ip to the variable which i will use later in my code as the ip address.
How do I make the checking in the button click event ?
This is what i tried now:
At the top of my MainActivity i added:
private final String[] ipaddresses = new String[2];
private final Integer[] ipports = new Integer[2];
Socket socket = null;
Then in the onCreate:
ipaddresses[0] = "10.0.0.3";
ipaddresses[1] = "10.0.0.2";
ipports[0] = 8098;
ipports[1] = 8088;
addListenerOnButton();
new Thread(new ClientThread()).start();
Then
public void addListenerOnButton() {
btnClick = (Button) findViewById(R.id.checkipbutton);
btnClick.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
try {
String str = btnClick.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
And the ClientThread
class ClientThread implements Runnable {
#Override
public void run() {
for (int i=0; i<ipaddresses.length; i++)
{
try
{
InetAddress serverAddr = InetAddress.getByName(ipaddresses[i]);
socket = new Socket(serverAddr, ipports[i]);
} catch (UnknownHostException e1)
{
e1.printStackTrace();
} catch (IOException e1)
{
e1.printStackTrace();
}
}
}
}
This is a screenshot of the exception message i'm getting:
The exception is on the line:
new OutputStreamWriter(socket.getOutputStream())),
You must open sockets to check server connectivity. Here is an example on you send strings to server on click event:
public class Client extends Activity {
private Socket socket;
private static final int SERVERPORT = 8099;
private static final String SERVER_IP = "10.0.0.3";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
So if you get an exception trying to connect to server, it means you haven't connectivity.
I have made an application that opens up a socket via a thread and updates based on what is typed. Here is the code:
Server.java:
public class Server {
public static void main(String[] args) throws IOException {
int portNumber = 2392;
boolean listening = true;
System.out.println("Server: Running...");
try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
System.out.println("Server: Connected to Client!");
while (listening) {
new ServerThread(serverSocket.accept()).start();
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection( '" + e.getMessage() + "' );");
} finally {
System.out.println("Server: Disconnecting...");
}
}
}
Server Thread.java:
public class ServerThread extends Thread {
private Socket socket = null;
Scanner reader = new Scanner(System.in);
public ServerThread(Socket socket) {
super("ServerThread");
this.socket = socket;
}
public void run() {
System.out.println("Ruasd");
try (PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
String outputLine = "";
while (!outputLine.equals("Disconnect")) {
outputLine = reader.nextLine();
out.println(outputLine);
}
socket.close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client.java:
public class MainActivity extends Activity {
private Socket socket;
private TextView status;
private BufferedReader in;
private Handler mHandler;
private static final int SERVERPORT = 2392;
private static final String SERVER_IP = "...ip#...";
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_vitals);
status = (TextView) findViewById(R.id.text_status);
new Thread(new CommunicationThread()).start();
}
#Override
protected void onStop() {
super.onStop();
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class CommunicationThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
final String fromServer = in.readLine();
System.out.println("Server: " + fromServer);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// This code will always run on the UI thread, therefore is safe to modify UI elements.
status.setText(fromServer);
}
});
if (fromServer.equals("Disconnect."))
break;
}
} catch (IOException e) {
e.printStackTrace();
}
It works perfectly the first time and outputs to the status TextView correctly. However, when I restart the application, it outputs every other word. For instance, If I type "Hey" "Hi "You" "How", I will see "Hi" and "How" in the TextView the second time I start the application.
What's really odd to me is that when I do System.out.println("Server: " + fromServer) it is outputting all values. Any suggestions are greatly appreciated.
Ok I think I found the problem (got it working for me, that is). In your CommunicationThread, you didn't have a while loop. Also, you need to iterate the server's input until it is null. See below:
class CommunicationThread implements Runnable {
#Override
public void run() {
try {
// keep the connection alive.
while (true) {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String fromServer;
// get server messages until there are none
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// This code will always run on the UI thread, therefore is safe to modify UI elements.
status.setText(fromServer);
}
});
if (fromServer.equals("Disconnect."))
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Please get back to me on how it works out :)
I've tried out almost everything.
Forwarding from ADB Shell using adb forward TCP:12345 TCP:12345
Using 10.0.2.2 (without forwarding) to listen to my host machine
Setting the INTERNET permission in the manifest
Setting the thread policy to permit all functions
I'm running my client java program in 12345 port and I have a ServerSocket in the Android program that listens over the same port. But when I run my client (after running the server program on the emulator) and enter the String that I want to transfer, I get the exception saying 'Connection Refused'.
java.net.ConnectException: Connection refused: connect
Here's my server program:
public class MainActivity extends Activity {
TextView tv;
ServerSocket ss = null;
String mClientMsg = "";
Thread myCommsThread = null;
public static final int SERVERPORT = 12345;
protected static final int MSG_ID = 0x1337;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = new TextView(this);
tv.setText("Nothing from client yet");
setContentView(tv);
this.myCommsThread = new Thread(new CommsThread());
this.myCommsThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
// make sure you close the socket upon exiting
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Handler myUpdateHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_ID:
// TextView tv = (TextView) findViewById(R.id.TextView01);
tv.setText(mClientMsg);
setContentView(tv);
break;
default:
break;
}
super.handleMessage(msg);
}
};
class CommsThread implements Runnable {
public void run() {
Socket s = null;
try {
ss = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
Message m = new Message();
m.what = MSG_ID;
try {
if (s == null)
s = ss.accept();
BufferedReader input = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String st = null;
st = input.readLine();
mClientMsg = st;
myUpdateHandler.sendMessage(m);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
My Java client program is as follows:
public class TCPSender {
public static void main(String args[]) {
try {
DataInputStream dis = new DataInputStream(System.in);
System.out.println("Enter the file name:");
#SuppressWarnings("deprecation")
String f = dis.readLine();
File f1 = new File(f);
FileReader fr = new FileReader(f1);
Socket s = new Socket("127.0.0.1", 12345);
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
pw.println(f);
int c = 0;
while ((c = fr.read()) != -1)
pw.println(c);
System.out.println("File content are sent....");
fr.close();
s.close();
} catch (Exception e) {
System.out.println("" + e);
}
}
}