I'm asking for a little help here..
I made a Android app in order to get messages from a server. The app just have to show the server's messages and nothing else.
the thing is nothing is shown in the UI, all the messages are shown when I disconnect the server.
It's frustrating because the app get the data's, just don't show them before the disconnection of the server.
Here is my code :
public class SlimpleTextClientActivity extends Activity {
private TextView textView;
private Socket client;
private PrintWriter printwriter;
private BufferedReader bufferedReader;
//Following is the IP address of the chat server. You can change this IP address according to your configuration.
// I have localhost IP address for Android emulator.
private String CHAT_SERVER_IP = "192.168.2.2";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_slimple_text_client);
textView = (TextView) findViewById(R.id.textView1);
ChatOperator chatOperator = new ChatOperator();
chatOperator.execute();
}
/**
* This AsyncTask create the connection with the server and initialize the
* chat senders and receivers.
*/
private class ChatOperator extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
try {
client = new Socket(CHAT_SERVER_IP, 6666); // Creating the server socket.
if (client != null) {
printwriter = new PrintWriter(client.getOutputStream(), true);
InputStreamReader inputStreamReader = new InputStreamReader(client.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
} else {
System.out.println("Server has not bean started on port 4444.");
}
} catch (UnknownHostException e) {
System.out.println("Faild to connect server " + CHAT_SERVER_IP);
e.printStackTrace();
} catch (IOException e) {
System.out.println("Faild to connect server " + CHAT_SERVER_IP);
e.printStackTrace();
}
return null;
}
/**
* Following method is executed at the end of doInBackground method.
*/
#Override
protected void onPostExecute(Void result) {
Receiver receiver = new Receiver(); // Initialize chat receiver AsyncTask.
receiver.execute();
}
}
/**
* This AsyncTask continuously reads the input buffer and show the chat
* message if a message is availble.
*/
private class Receiver extends AsyncTask<Void, Void, Void> {
private String message;
#Override
protected Void doInBackground(Void... params) {
while (true) {
try {
if (bufferedReader.ready()) {
message = bufferedReader.readLine();
publishProgress(null);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
#Override
protected void onProgressUpdate(Void... values) {
textView.append( message + "\n");
}
}
}
Hope that someone have an idea because here... I don't x)
Simon !
EDIT :
So... I went to java to test my code (simplification with the System.out.println)
Here is my code :
public class MainClass {
public static void main(String[] args) throws Exception {
final Socket client;
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
try{
client = new Socket("192.168.2.2", 6666);
InputStreamReader inputStreamReader = new InputStreamReader(client.getInputStream());
// create new buffered reader
br = new BufferedReader(inputStreamReader);
int value=0;
String monChar = null;
String maChaine = null;
//System.out.println(maChaine);
// reads to the end of the stream
while((value = br.read()) != -1)
{
// converts int to character
char c = (char) value;
maChaine = maChaine + c;
}
}catch(Exception e){
e.printStackTrace();
}finally{
// releases resources associated with the streams
if(is!=null)
is.close();
if(isr!=null)
isr.close();
if(br!=null)
br.close();
}
}
}
The thing is that I can't reach maChaine.
This does the same thing that before : I only can reach my String when the server is disconected.
If I put a "System.out.println(maChaine);" in my While it will print something at each rows and if I put it after it will only do something if the server is disconected.
Related
I am working on a chat client application and I have made a server. I managed to make the client connect to the server, but then when I send a message to the server, there's no reaction from the server.
Here is the part of the code of my server that is not working
class ClientConnect implements Runnable {
private DataInputStream in = null;
private DataOutputStream out = null;
Socket client;
ClientConnect(Socket client) {
try {
this.client = client;
/* obtain an input stream to this client ... */
in = new DataInputStream (client.getInputStream());
/* ... and an output stream to the same client */
setOut(new DataOutputStream (client.getOutputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
String msg, response;
ChatServerProtocol protocol = new ChatServerProtocol(this);
try {
while (true) {
if (in.available() > 0){
msg = in.readUTF();
response = protocol.process(msg);
getOut().writeBytes("SERVER: " + response);
}
}
} catch (IOException e) {
System.err.println(e);
} finally {
// The connection is closed for one reason or another
try {
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void sendMsg(String msg) {
try {
getOut().writeBytes(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public DataOutputStream getOut() {
return out;
}
public void setOut(DataOutputStream out) {
this.out = out;
}
}
And here is the client :
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String response = null;
EditText nicknameField = (EditText)findViewById(R.id.nicknameField);
EditText passwordField = (EditText)findViewById(R.id.passwordField);
nickname = nicknameField.getText().toString();
password = passwordField.getText().toString();
switch(v.getId()){
case R.id.signin:
new SendMessage(this).execute("SIGNUP " + nickname + " " + password );
break;
case R.id.signup:
new SendMessage(this).execute("SIGNUP " + nickname + " " + password );
break;
}
}
private String onPostExecuteSendMessage() {
return null;
}
public void showMessage(String response) {
Builder builder = new AlertDialog.Builder(this);
builder.setMessage(response);
AlertDialog dialog = builder.create();
dialog.show();
}
public void getClientSocket(Socket client) {
this.client = client;
try {
out = new DataOutputStream (client.getOutputStream());
in = new DataInputStream (client.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public DataOutputStream getOut() {
// TODO Auto-generated method stub
return this.out;
}
public DataInputStream getIn() {
// TODO Auto-generated method stub
return this.in;
}
public void goMenuChat() {
// TODO Auto-generated method stub
Intent intent = new Intent(this, MenuChatActivity.class);
startActivity(intent);
}
}
Also I used an Asynctask to send message from the client :
package client.chatclient;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import android.os.AsyncTask;
public class SendMessage extends AsyncTask<String, String, String> {
private static final String msg_OK = "OK";
private static final String msg_NICK_IN_USE = "NICK IN USE";
private static final String msg_UNKNOWN_CMD = "UNKNOWN CMD";
private static final String msg_INVALID = "INVALID COMMAND";
private static final String msg_SEND_FAILED = "FAILED TO SEND";
private static final String msg_INCORRECT_IDS = "INCORRECT IDS";
private static final String msg_DISCONNECT = "DISCONNECT";
private WeakReference<MainActivity> activity;
private String message;
private String response = "";
private DataOutputStream out;
private DataInputStream in;
public SendMessage(MainActivity act){
super();
activity = new WeakReference<MainActivity>(act);
}
protected String doInBackground(String... message) {
this.message = message[0];
this.out = activity.get().getOut();
this.in = activity.get().getIn();
try {
out.writeBytes(this.message);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response = convertStreamToString(this.in);
return response;
}
protected void onPostExecute(String response) {
if ((response == msg_INCORRECT_IDS) || (response == msg_NICK_IN_USE)){
activity.get().showMessage(response);
}
else if (response == msg_OK){
activity.get().goMenuChat();
}
}
private static String convertStreamToString(DataInputStream in) {
/*
* To convert the InputStream to String we use the
* BufferedReader.readLine() method. We iterate until the BufferedReader
* return null which means there's no more data to read. Each line will
* appended to a StringBuilder and returned as String.
*/
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
I send my message from the client by clicking on a button then it goes to the SendMessage class, and send the message to the server and normally the server should receive my message in the loop "while (true)..." and sends back a response according to the protocol that I've implemented.
I really don't know what is wrong. If you know how to solve this issue or have some solutions, please tell me ! If you want more details, ask me ! :)
Thank you very much !
EDIT:
I instanciated my ClientConnect here
public class ChatServer {
private static int port = 8080;
public static void main (String[] args) throws IOException {
ServerSocket server = new ServerSocket(port); /* start listening on the port */
System.out.println( "Listening on "+ server );
Socket client = null;
while(true) {
try {
client = server.accept();
System.out.println( "Connection from " + client );
/* start a new thread to handle this client */
Thread t = new Thread(new ClientConnect(client));
t.start();
} catch (IOException e) {
System.err.println("Accept failed.");
System.err.println(e);
System.exit(1);
server.close();
}
}
}
}
EDIT: I found where the problem is. I put some log() statements as you said
log.d(null,"beforeconvert")
try {
log.d(null,"convert")
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
log.d(null,"errorconvert")
e.printStackTrace();
}
After that in logcat, it just shows "beforeconvert". I don't really know what the problem is ? while ((line = reader.readLine()) != null) is surely the problem. When I use the debugger step by step in eclipse, it stops at this line and doesn't even go inside the loop.
EDIT : I REALLY don't know why, but when I quit the emulator when running my app, it shows everything.
Listening on ServerSocket[addr=0.0.0.0/0.0.0.0,localport=8080]
Connection from Socket[addr=/127.0.0.1,port=56646,localport=8080]
client connected
msg received
error !
SIGNUP Nickname Password
SIGNUP Nickname Password
msg converted
OK
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.DataInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at server.ClientConnect.convertStreamToString(ChatServer.java:357)
at server.ClientConnect.run(ChatServer.java:304)
at java.lang.Thread.run(Unknown Source)
java.net.SocketException: Connection reset by peer: socket write error
When you are writing data to output stream in the end you need to flush
this.out.flush();
I think this is why the data is not sent and received
Hope that helps.
Edit:
Let me try to explain in general idea..
When you are opening a socket you have a connection to another machince.
So the
in.available();
and
socket.accpet();
Should work.. once you are writing into outputstream you must flush in order to see the data(or close, i think it flushes before it get closed).
Anyway i attach a link to an example.. You should try this one, Or look at parts you have problem with..
http://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/
I "wrote" some code which should execute http request + stream download, however it does not seem to be working with the second part. It connects to the server, but without getting the expected data from it. The first few times it evena worked out, it displayed the html data from google, but afterwards,
I tried to optimize my code and threw something away, added something here and there, extended it by a class etc., which probably caused the "error". Here is my code:
public class MainActivity extends ActionBarActivity {
private static final String TAG = null;
TextView httpStuff;
public static String info;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
AsyncDownload data = (AsyncDownload) new AsyncDownload().execute();
info = data.get();
httpStuff.setText(info);
} catch (Exception e){
e.printStackTrace();
}
}
public class AsyncDownload extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... params) {
Log.v(TAG, "Final Requsting URL is : :" + "google.com");
String line = "";
String responseData = null;
try {
StringBuilder sb = new StringBuilder();
String x = "";
URL httpurl = new URL("http://www.google.com");
URLConnection tc = httpurl.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(tc.getInputStream()));
while ((line = in.readLine()) != null) {
sb.append(line + "\n");
x = sb.toString();
}
responseData = new String(x);
}
catch (UnknownHostException uh){
Log.v("NewWebHelper", "Unknown host :");
uh.printStackTrace();
}
catch (FileNotFoundException e) {
Log.v("NewWebHelper", "FileNotFoundException :");
e.printStackTrace();
}
catch (IOException e) {
Log.v("NewWebHelper", "IOException :");
e.printStackTrace();
}
catch (Exception e) {
Log.v("NewWebHelper", "Exception :");
e.printStackTrace();
}
return responseData;
}
}
I just don't know what's the missing thing. I've been trying to solve this for hours with a big variety of data-passing versions of this, but nothing seems to be working. I'm counting on you, brainiacs.
now i'm making socket connection to connect multiple client to one server. everything fine, i make thread in different class. But when i will fill textView with string from thread activity, i can't. please help
this MainActivity:
public class MainActivity extends Activity {
private static int port = 6000;
TextView txt;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt = (TextView) findViewById(R.id.txtCommand);
txt.setText("Server : ");
ServerSocket server1 = null;
Server gameServer = new Server();
try {
server1 = new ServerSocket(port);
// .. server setting should be done here
} catch (IOException e) {
System.out.println("Could not start server!");
// return ;
}
while (true) {
Socket client = null;
try {
client = server1.accept();
gameServer.handleConnection(client);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Server {
private ExecutorService executor = Executors.newCachedThreadPool();
public void handleConnection(Socket client) throws IOException {
PlayerConnection newPlayer = new PlayerConnection(this, client);
txt.setText(newPlayer.getuname());
this.executor.execute(newPlayer);
}
// add methods to handle requests from PlayerConnection
}
and this thread adctivity :
public class PlayerConnection implements Runnable {
private Server parent;
private Socket socket;
private PrintWriter out;
private BufferedReader in;
String line;
protected PlayerConnection(Server parent, Socket socket) throws IOException {
this.parent = parent;
this.socket = socket;
this.in = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
this.out = new PrintWriter(new OutputStreamWriter(
socket.getOutputStream()));
}
public void run() {
while(!this.socket.isClosed()) {
try {
//int nextEvent = this.in.readInt();
line = in.readLine();
System.out.println("Server Receive : "
+ line);
out.println("Server Sent :" +line);
System.out.println("SEND : "
+ line);
out.flush();
if (line == null){
this.socket.isClosed();
break;
}
} catch (IOException e) {}
}
I realized that you have a while loop that never ends in your onCreate method. try to move that loop in to your thread. this loop blocks inputs of your application.
while (true) {
Socket client = null;
try {
client = server1.accept();
gameServer.handleConnection(client);
} catch (IOException e) {
e.printStackTrace();
}
you can use handler or runOnUiThread method.
I'm working on a test project, something like a basic chat program using wi-fi connection.
I'm creating sockets to connect two different devices, but my problem is that when I send the first message, it's showing in the other device. But if I try to send again, I can see in the logs from the first one, that the message is sent, but it never shows up in the second device.
I've tried to implement the reading of the received data in another thread..or in Async Task, but the problem is still there. Here are both ways of my implementation :
Single Thread :
public void listenForSocket(){
thread = new Thread(new Runnable() {
public void run() {
Log.e("READDATAFROMSOCKET","READDATAFROMSOCKET");
try {
// sets the service running state to true so we can get it's state from other classes and functions.
serverSocket = new ServerSocket(DNSUtils.port);
client = serverSocket.accept();
client.setKeepAlive(true);
InputStream is = client.getInputStream();
Log.d("","is Size : "+is.available());
BufferedReader in = new BufferedReader(new InputStreamReader(is));
int readed = in.read();
Log.d("","readed bytes : "+readed);
String line = "";
while ((line = in.readLine()) != null) {
Log.i("","line : "+line);
changeText(line);
}
//client.close();
//serverSocket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
}
And here is AsyncTask :
class ServerTask extends AsyncTask<Void, Void, Void>{
private String line = "";
#Override
protected Void doInBackground(Void... params) {
try {
Log.e("ASYNCTASK","ASYNCTASK");
// sets the service running state to true so we can get it's state from other classes and functions.
serverSocket = new ServerSocket(DNSUtils.port);
client = serverSocket.accept();
client.setKeepAlive(true);
InputStream is = client.getInputStream();
Log.d("","is Size : "+is.available());
BufferedReader in = new BufferedReader(new InputStreamReader(is));
int readed = in.read();
Log.d("","readed bytes : "+readed);
while ((line = in.readLine()) != null) {
Log.i("","line : "+line);
}
//client.close();
//serverSocket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
changeText(line);
}
}
changeText(String); -
private void changeText(final String line) {
runOnUiThread(new Runnable() {
#Override
public void run() {
LinearLayout.LayoutParams params = new LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.RIGHT;
TextView sendMsg = new TextView(MainActivity.this);
sendMsg.setText(DNSUtils.clientName+" : "+line);
sendMsg.setTextColor(Color.DKGRAY);
sendMsg.setTextSize(18);
layout.addView(sendMsg, params);
}
});
}
Any ideas how to fix this issue?
And another problem is that when I am reading the received data, the first letter of the sent string never shows. It always starts from the second letter.
Thanks in advance.
If i were you i will try to implement serverSocket = new ServerSocket(DNSUtils.port); only once with new; not in every thread.
I have an android client and a java server that use the same socket to send each other a string, but actually doesn't work and I don't know why.
Anyway, I need to use just one socket.
Here's the code for client and server:
public class CliActivity extends Activity implements OnClickListener {
Button b;
TextView tv;
BufferedReader in = null;
PrintStream out = null;
Socket client = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b =(Button)findViewById(R.id.button1);
tv =(TextView)findViewById(R.id.textView1);
b.setOnClickListener(this);
}
public void onClick(View v) {
try {
client = new Socket("192.168.0.3",9000);
out = new PrintStream(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out.write(("How are you?").getBytes());
out.close();
String message = in.readLine();
tv.setText(message);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server:
public class server {
public static void main(String[] args) {
BufferedReader in = null;
PrintStream out = null;
Socket client = null;
try {
ServerSocket server = new ServerSocket(9000);
client = server.accept();
out = new PrintStream(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String message = in.readLine();
System.out.println(message);
out.write(("fine thanx").getBytes());
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Any suggestion?