I have very strange problem with telnet communication. When I send a message to server, server will reply every time after next message. Server reply looks like this:
// bad IP transmitters adress message
If I send "first message" server will not reply. After I send "second message" server will reply to the first message. Every time reply from server is one message late.
My communication looks like this:
If I use Telnet application from Google Play Store it works perfect and communication looks like this:
C: first message
S: [// bad IP transmitters adress message 'first message']
C: second message
S: [// bad IP transmitters adress message 'second message']
C: third message
S: [// bad IP transmitters adress message 'third message']
Is there some way how fix it? Thank you so much!
Code:
TCPclass
public class TCPclass {
private boolean mRun = false;
String messageFromServer;
private OnMessageReceived mMessageListener = null;
PrintWriter out;
BufferedReader in;
public TCPclass(OnMessageReceived listener) {
mMessageListener = listener;
}
public void stopClient() {
mRun = false;
}
public void sendMessage(String message) {
if (out != null && !out.checkError()) {
message = message + '\r' + '\n';
out.print(message);
out.flush();
Log.i("Terminal", "Message sent.");
}
}
public void start(String hostname, int port) {
mRun = true;
try {
InetAddress serverAddr = InetAddress.getByName(hostname);
Socket socket = new Socket(serverAddr, port);
try {
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
// receive the message which the server sends back
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
while (mRun) {
do
{
String messageFromServer = in.readLine();
if (messageFromServer != null && mMessageListener != null) {
mMessageListener.messageReceived(messageFromServer); //append message to Text View
}
messageFromServer = null;
} while (in.ready());
}
} catch (Exception e) {
Log.e("Terminal", "S: Error ", e);
} finally {
socket.close();
}
} catch (Exception e) {
Log.e("Terminal", "Establish connection error " + hostname + " "
+ port);
}
}
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
MainActivity class:
public class MainActivity extends Activity {
private TCPclass mTcpClass;
public String hostname = "127.0.0.1";
public int port = 7011;
TextView serverMessage;
private connectTask mTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText IPaddress = (EditText) findViewById(R.id.eAddress);
final EditText ePort = (EditText) findViewById(R.id.ePort);
final EditText eMessage = (EditText) findViewById(R.id.eMessage);
serverMessage = (TextView) findViewById(R.id.tOutput);
Button okButton = (Button) findViewById(R.id.bOK); //Connect button
okButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) { // connect
// TODO Auto-generated method stub
hostname = IPaddress.getText().toString();
String strPort = ePort.getText().toString();
try {
port = Integer.parseInt(strPort);
} catch (NumberFormatException e) {
Log.e(strPort, "Error port");
}
mTask = new connectTask();
mTask.execute("");
}
});
Button sendButton = (Button) findViewById(R.id.bSend);
sendButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String message = eMessage.getText().toString();
serverMessage.append("C: " + message + "\n");
Log.i("Terminal", "Sending message " + message);
if (mTcpClass != null) {
mTcpClass.sendMessage(message);
}
eMessage.setText("");
}
});
}
public class connectTask extends AsyncTask<String, String, TCPclass> {
#Override
protected TCPclass doInBackground(String... message) {
Log.i("Terminal", "doInBackground.");
mTcpClass = new TCPclass(new TCPclass.OnMessageReceived() {
#Override
// here the messageReceived method is implemented
public void messageReceived(String message) {
// this method calls the onProgressUpdate
publishProgress(message);
}
});
mTcpClass.start(hostname, port);
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
serverMessage.append("S: " + Arrays.toString(values) + "\n");
}
}
It seems to me that the server is probably sending a blank or extra line somewhere that you haven't accounted for. I'm the world's last and least fan of calling available() or ready() but maybe this is a case for it:
do
{
String response = in.readLine();
// ...
} while (in.ready());
... at least for debugging purposes, until you sort out exactly what the response is to each line you send. Note that using a while loop here would be definitely incorrect.
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 have made an app that should connect to a sensor via WiFi Direct, then connect to port 5001 on the sensor to get the sensor data.
I have used "Simple Socket Tester" to start a server on another phone to see if my app succeeded in connecting to port 5001 on that server. When connected, I can send messages to the server, which is displayed on the other phone. But when I send messages to the client from the other phone, I am not receiving the message in my app.
Why is that? Am I missing something inside my code?
public class TCPClient {
public static final String SERVER_IP = "192.168.1.52"; //your computer IP address
public static final int SERVER_PORT = 5001;
// message to send to the server
private String mServerMessage;
// sends message received notifications
private OnMessageReceived mMessageListener = null;
// while this is true, the server will continue running
private boolean mRun = false;
// used to send messages
private PrintWriter mBufferOut;
// used to read messages from the server
private BufferedReader mBufferIn;
/**
* Constructor of the class. OnMessagedReceived listens for the messages received from server
*/
public TCPClient(OnMessageReceived listener) {
mMessageListener = listener;
}
/**
* Sends the message entered by client to the server
*
* #param message text entered by client
*/
public void sendMessage(String message) {
if (mBufferOut != null && !mBufferOut.checkError()) {
mBufferOut.println(message);
mBufferOut.flush();
}
}
/**
* Close the connection and release the members
*/
public void stopClient() {
// send mesage that we are closing the connection
/*sendMessage(Constants.CLOSED_CONNECTION+"Kazy");*/
mRun = false;
if (mBufferOut != null) {
mBufferOut.flush();
mBufferOut.close();
}
mMessageListener = null;
mBufferIn = null;
mBufferOut = null;
mServerMessage = null;
}
public void run() {
mRun = true;
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVER_PORT);
try {
//sends the message to the server
mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
//receives the message which the server sends back
mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// send login name
sendMessage("hi");
//in this while the client listens for the messages sent by the server
while (mRun) {
mServerMessage = mBufferIn.readLine();
if (mServerMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(mServerMessage);
}
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
socket.close();
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
//Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
//class at on asynckTask doInBackground
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
The class where my ConnectTask class is.
public class DeviceDetailFragment extends Fragment implements ConnectionInfoListener {
protected static final int CHOOSE_FILE_RESULT_CODE = 20;
private View mContentView = null;
private WifiP2pDevice device;
private WifiP2pInfo info;
ProgressDialog progressDialog = null;
TCPClient mTCPClient;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContentView = inflater.inflate(R.layout.device_detail, null);
mContentView.findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC;
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel",
"Connecting to :" + device.deviceAddress, true, true
// new DialogInterface.OnCancelListener() {
//
// #Override
// public void onCancel(DialogInterface dialog) {
// ((DeviceActionListener)
getActivity()).cancelDisconnect();
// }
// }
);
((DeviceListFragment.DeviceActionListener) getActivity()).connect(config);
}
});
mContentView.findViewById(R.id.btn_disconnect).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
((DeviceListFragment.DeviceActionListener) getActivity()).disconnect();
}
});
/*
mContentView.findViewById(R.id.btn_start_client).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// Allow user to pick an image from Gallery or other
// registered apps
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
}
});
*/
return mContentView;
}
#Override
public void onConnectionInfoAvailable(final WifiP2pInfo info) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
this.info = info;
this.getView().setVisibility(View.VISIBLE);
// The owner IP is now known.
TextView view = (TextView) mContentView.findViewById(R.id.group_owner);
view.setText(getResources().getString(R.string.group_owner_text)
+ ((info.isGroupOwner == true) ? getResources().getString(R.string.yes)
: getResources().getString(R.string.no)));
// InetAddress from WifiP2pInfo struct.
view = (TextView) mContentView.findViewById(R.id.device_info);
view.setText("Group Owner IP - " + info.groupOwnerAddress.getHostAddress());
if(info.groupFormed) {
new ConnectTask().execute("");
if (mTCPClient != null) {
mTCPClient.sendMessage("testing");
}
//sends the message to the server
}
// After the group negotiation, we assign the group owner as the file
// server. The file server is single threaded, single connection server
// socket.
/*
if (info.groupFormed && info.isGroupOwner) {
new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text))
.execute();
}
*/
// hide the connect button
mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
}
/**
* Updates the UI with device data
*
* #param device the device to be displayed
*/
public void showDetails(WifiP2pDevice device) {
this.device = device;
this.getView().setVisibility(View.VISIBLE);
TextView view = (TextView) mContentView.findViewById(R.id.device_address);
view.setText(device.deviceAddress);
view = (TextView) mContentView.findViewById(R.id.device_info);
view.setText(device.toString());
}
/**
* Clears the UI fields after a disconnect or direct mode disable operation.
*/
public void resetViews() {
mContentView.findViewById(R.id.btn_connect).setVisibility(View.VISIBLE);
TextView view = (TextView) mContentView.findViewById(R.id.device_address);
view.setText(R.string.empty);
view = (TextView) mContentView.findViewById(R.id.device_info);
view.setText(R.string.empty);
view = (TextView) mContentView.findViewById(R.id.group_owner);
view.setText(R.string.empty);
/*
view = (TextView) mContentView.findViewById(R.id.status_text);
view.setText(R.string.empty);
this.getView().setVisibility(View.GONE);
*/
}
public class ConnectTask extends AsyncTask<String, String, TCPClient> {
#Override
protected TCPClient doInBackground(String... message) {
//we create a TCPClient object
mTCPClient = new TCPClient(new TCPClient.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(String message) {
//this method calls the onProgressUpdate
publishProgress(message);
}
});
mTCPClient.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
//response received from server
Log.d("test", "response " + values[0]);
//process server response here....
}
}
}
I'm working on an android Quiz app with connection to a server over a socket. On the client side (Android device) I check in a while loop the answers which are given by a server (Java server). The connection and the receiving of the answer all goes good. The problem is that in my class to check for answers there's a bug. To give more information I will include a part of the code here:
public void startClient(){
checkValue = new Thread(new Runnable(){
#Override
public void run() {
try
{
final int PORT = 4444;
final String HOST = "192.168.1.118";
Socket SOCK = new Socket(HOST, PORT);
Log.e("success", "You connected to: " + HOST);
quizClient = new QuizClient(SOCK);
//Send the groupname to the list
PrintWriter OUT = new PrintWriter(SOCK.getOutputStream());
OUT.println(groupName);
OUT.flush();
Thread X = new Thread(quizClient);
X.start();
connected = true;
}
catch(Exception X)
{
Log.e("connection error", "Error: ", X);
}
}
});
checkValue.start();
}
public void testvalue(){
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
while(true){
if(message != null && !message.matches("")){
Thread.sleep(1000);
Log.e("receive", message);
buffer = message;
message = "";
Message msg = new Message();
String textTochange = buffer;
msg.obj = textTochange;
mHandler.sendMessage(msg);
Thread.sleep(3000);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
String text = (String)msg.obj;
//call setText here
//String[] myStringArray = new String[];
value.clear();
String[] items = text.split(";");
for (String item : items)
{
value.add(item);
Log.e("message", item);
//System.out.println("item = " + item);
}
if(value.get(0).equals("1")){
questionGroup.setVisibility(View.INVISIBLE);
sendAnswer.setVisibility(View.INVISIBLE);
answer.setVisibility(View.INVISIBLE);
question.setText("");
question.setText(value.get(2));
rad1.setText(value.get(3));
rad2.setText(value.get(4));
rad3.setText(value.get(5));
rad4.setText(value.get(6));
questionGroup.setVisibility(View.VISIBLE);
sendAnswer.setVisibility(View.VISIBLE);
} else if (value.get(0).equals("2")){
questionGroup.setVisibility(View.INVISIBLE);
sendAnswer.setVisibility(View.INVISIBLE);
answer.setVisibility(View.INVISIBLE);
question.setText("");
question.setText(value.get(2));
answer.setVisibility(View.VISIBLE);
sendAnswer.setVisibility(View.VISIBLE);
} else
{
questionGroup.setVisibility(View.INVISIBLE);
sendAnswer.setVisibility(View.INVISIBLE);
answer.setVisibility(View.INVISIBLE);
question.setText(text);
}
}
};
#Override
protected void onStop()
{
if (connected == true){
try {
quizClient.DISCONNECT();
} catch (IOException e) {
e.printStackTrace();
}
}
if(checkValue != null)
{
checkValue.interrupt();
}
super.onStop();
closeApplication();
}
So I make a new instance of this class (where I actually check the incoming stream of data)
public class QuizClient implements Runnable {
//Globals
Socket SOCK;
Scanner INPUT;
Scanner SEND = new Scanner(System.in);
PrintWriter OUT;
public QuizClient(Socket X)
{
this.SOCK = X;
}
public void run()
{
try
{
try
{
INPUT = new Scanner(SOCK.getInputStream());
OUT = new PrintWriter(SOCK.getOutputStream());
OUT.flush();
CheckStream();
}
finally
{
SOCK.close();
}
}
catch(Exception X)
{
Log.e("error", "error: ", X);
}
}
public void DISCONNECT() throws IOException
{
OUT.println("DISCONNECT");
OUT.flush();
SOCK.close();
}
public void CheckStream()
{
while(true)
{
RECEIVE();
}
}
public void RECEIVE()
{
if(INPUT.hasNext())
{
String MESSAGE = INPUT.nextLine();
if(MESSAGE.contains("#?!"))
{
}
else
{
QuizActivity.message = MESSAGE;
Log.e("test", MESSAGE);
}
}
}
public void SEND(String X)
{
OUT.println(X);
OUT.flush();
}
}
So the bug persist I think in the following class:
public void testvalue(){
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
while(true){
if(message != null && !message.matches("")){
Thread.sleep(1000);
Log.e("receive", message);
buffer = message;
message = "";
What I do here is make a thread and check if the "message" is not equals at null. The message come from the other class:
public void RECEIVE()
{
if(INPUT.hasNext())
{
String MESSAGE = INPUT.nextLine();
if(MESSAGE.contains("#?!"))
{
}
else
{
QuizActivity.message = MESSAGE;
Now most of the time this works good but there are 2 problems. When I go out of the page it disconnect from the server (works) I go back on the page and connect again to the server but this time I don't get any values on the screen (receiving is okj but for one of the other reason it does not go good in my handler). Also get an indexoutofboundexception after a time:
question.setText(value.get(2));
A second problem occurs some time while the program runs. There are moments that I also don't get a value on my interface while it correctly receive the input.
So my guess is that my solution of the thread to read in the values is not the best way to handle it. So now I ask to people with more experience what I can do to make this work without major problems? You need to know the connection works and I get the value in my QuizClient class. So the problem need to be in my main class.
My oncreate class:
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
selectgroep = (Spinner) findViewById(R.id.groepen);
questionGroup = (RadioGroup) findViewById(R.id.QuestionGroup);
sendAnswer = (Button) findViewById(R.id.sendAnswer);
rad1 = (RadioButton) findViewById(R.id.radio0);
rad2 = (RadioButton) findViewById(R.id.radio1);
rad3 = (RadioButton) findViewById(R.id.radio2);
rad4 = (RadioButton) findViewById(R.id.radio3);
answer = (EditText) findViewById(R.id.textanswer);
questionGroup.setVisibility(View.INVISIBLE);
sendAnswer.setVisibility(View.INVISIBLE);
answer.setVisibility(View.INVISIBLE);
try {
connect();
} catch (InterruptedException e) {
e.printStackTrace();
}
//Code na het drukken op de knop
startserver = (Button) findViewById(R.id.startserver);
startserver.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startClient();
getID();
testvalue();
}
});
sendAnswer.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Stuur antwoord door en sluit alles af
questionGroup.setVisibility(View.INVISIBLE);
sendAnswer.setVisibility(View.INVISIBLE);
answer.setVisibility(View.INVISIBLE);
answer.setText("");
rad1.setChecked(true);
rad1.setText("");
rad2.setText("");
rad3.setText("");
rad4.setText("");
question.setText("Wachten op server ... ");
}
});
}
Thank you in advance,
Thomas Thooft
I am trying to write a TCP client using Sockets in java, however I cannot seem to read data sent from the server to the client. Some time i will received from server but not all time..
public class TCPClient {
private String serverMessage;
public static final String SERVERIP = "103.13.97.87"; //your computer IP address
public static final int SERVERPORT = 8101;
private OnMessageReceived mMessageListener = null;
private boolean mRun = false;
PrintWriter out;
BufferedReader in;
/**
* Constructor of the class. OnMessagedReceived listens for the messages received from server
*/
public TCPClient(OnMessageReceived listener) {
mMessageListener = listener;
}
/**
* Sends the message entered by client to the server
* #param message text entered by client
*/
public void sendMessage(String message){
if (out != null && !out.checkError()) {
out.println(message);
out.flush();
}
}
public void stopClient(){
mRun = false;
}
public void run() {
mRun = true;
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVERPORT);
try {
//send the message to the server
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
Log.e("TCP Client", "C: Sent.");
Log.e("TCP Client", "C: Done.");
//receive the message which the server sends back
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//in this while the client listens for the messages sent by the server
while (mRun) {
serverMessage = in.readLine();
if (serverMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(serverMessage);
}
serverMessage = null;
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + serverMessage + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
socket.close();
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
//Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
//class at on asynckTask doInBackground
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
My CustomAdpter.java
public class MyCustomAdapter extends BaseAdapter {
private ArrayList<String> mListItems;
private LayoutInflater mLayoutInflater;
public MyCustomAdapter(Context context, ArrayList<String> arrayList){
mListItems = arrayList;
//get the layout inflater
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
//getCount() represents how many items are in the list
return mListItems.size();
}
#Override
//get the data of an item from a specific position
//i represents the position of the item in the list
public Object getItem(int i) {
return null;
}
#Override
//get the position id of the item from the list
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
//check to see if the reused view is null or not, if is not null then reuse it
if (view == null) {
view = mLayoutInflater.inflate(R.layout.list_item, null);
}
//get the string item from the position "position" from array list to put it on the TextView
String stringItem = mListItems.get(position);
if (stringItem != null) {
TextView itemName = (TextView) view.findViewById(R.id.list_item_text_view);
if (itemName != null) {
//set the item name on the TextView
itemName.setText(stringItem);
}
}
//this method must return the view corresponding to the data at the specified position.
return view;
}
}
MainActivity.java
public class MainActivity extends Activity
{
private ListView mList;
private ArrayList<String> arrayList;
private MyCustomAdapter mAdapter;
private TCPClient mTcpClient;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arrayList = new ArrayList<String>();
final EditText editText = (EditText) findViewById(R.id.editText);
Button send = (Button)findViewById(R.id.send_button);
//relate the listView from java to the one created in xml
mList = (ListView)findViewById(R.id.list);
mAdapter = new MyCustomAdapter(this, arrayList);
mList.setAdapter(mAdapter);
// connect to the server
new connectTask().execute("");
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//String message = editText.getText().toString();
String message = "mall: ABC Mall date: 08/08/2013 time: 13:45 md5 f6151b2cdc256be4971bcc30629bbc7\r\n";
/* String str =md5Digest(message);
String s=message+str;*/
//add the text in the arrayList
arrayList.add("c: " + message);
//sends the message to the server
if (mTcpClient != null) {
mTcpClient.sendMessage(message);
/*mTcpClient.sendMessage(s);*/
}
//refresh the list
mAdapter.notifyDataSetChanged();
editText.setText("");
}
});
}
public class connectTask extends AsyncTask<String,String,TCPClient> {
#Override
protected TCPClient doInBackground(String... message) {
//we create a TCPClient object and
mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(String message) {
//this method calls the onProgressUpdate
publishProgress(message);
}
});
mTcpClient.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
//in the arrayList we add the messaged received from server
arrayList.add(values[0]);
// notify the adapter that the data set has changed. This means that new message received
// from server was added to the list
mAdapter.notifyDataSetChanged();
}
}
public static final String md5Digest(final String text)
{
try
{
// Create MD5 Hash
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
digest.update(text.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
int messageDigestLenght = messageDigest.length;
for (int i = 0; i < messageDigestLenght; i++)
{
String hashedData = Integer.toHexString(0xFF & messageDigest[i]);
while (hashedData.length() < 2)
hashedData = "0" + hashedData;
hexString.append(hashedData);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
return ""; // if text is null then return nothing
}
#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;
}
}
I have got huge problem with my Android app and I would like to ask you for help.
I am currently writing Android Clietn-Server app using sockets. I have found lots of tutorils on the Internet and from them I have created basics for my project. However, all tutorials are only for one message send and that's all. I need to send more of them so I've been trying to modify it.
This are code fragments responsible for server and client. The rest is not important at this time.
Server:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
serverStatus = (TextView) findViewById(R.id.server_status);
recivedMsg = (TextView)findViewById(R.id.rec_msg);
SERVERIP = getLocalIpAddress();
Thread fst = new Thread(new ServerThread());
fst.start();
}
public class ServerThread implements Runnable {
public void run() {
try {
if (SERVERIP != null) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP);
}
});
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// listen for incoming clients
Socket client = serverSocket.accept();
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Connected." + System.getProperty("line.separator"));
}
});
try {
line = null;
while (connected) {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
if((line = in.readLine())!=null)
{
Log.d("ServerActivity", line);
handler.post(new Runnable() {
#Override
public void run() {
if(recivedMsg.equals("CLOSE"))
{
recivedMsg.append("CLOSE socket");
connected = false;
}
else
{
recivedMsg.append("MSG: " + line + System.getProperty("line.separator"));
}
// do whatever you want to the front end
// this is where you can be creative
}
});
}
else
{
recivedMsg.append("empty" + System.getProperty("line.separator"));
}
}
break;
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
} else {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Error");
}
});
e.printStackTrace();
}
}
}
Client
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
serverIp = (EditText) findViewById(R.id.server_ip);
connectPhones = (Button) findViewById(R.id.connect_phones);
sendField = (EditText) findViewById(R.id.send_field);
sendMsg = (Button) findViewById(R.id.msg_send);
connectPhones.setOnClickListener(connectListener);
sendMsg.setOnClickListener(sendMessage);
}
#Override
protected void onStop() {
super.onStop();
try {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = "CLOSE";
out.write(outMsg);
out.flush();
// make sure you close the socket upon exiting
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private OnClickListener connectListener = new OnClickListener() {
#Override
public void onClick(View v) {
serverIpAddress = serverIp.getText().toString();
runTcpConnection();
sendMessageToServer("Msg");
}
};
private OnClickListener sendMessage = new OnClickListener() {
#Override
public void onClick(View v) {
sendMessageToServer(sendField.getText().toString());
}
};
private void runTcpConnection() {
try {
s = new Socket(serverIpAddress, SERVERPORT);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = "TCP connecting to " + SERVERPORT + System.getProperty("line.separator");
out.write(outMsg);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
SystemClock.sleep(10);
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
};
public void sendMessageToServer(String str) {
try {
s = new Socket(serverIpAddress, SERVERPORT);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = str + System.getProperty("line.separator");
out.write(outMsg);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("", "hello222");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("", "hello4333");
}
}
For now devices connect correctly. Moreover They are sending the first connection messages (those in OnClickListener connectListener). The problem is that when I am trying to send another message using sendMessageToServer it is impossible. Those messages shows only after client activity is destroyed.
Very interesting is that without SystemClock.sleep(10); listener runTcpConnection() behave strange. Only 'Connected.' displays on server.
Can someone tell me what I have to do to be able to send messages normally?
EDIT:
This are things that I have found:
If I am at the connection sending more messages than all are empty (null) and after the second one connection error shows - please reconnect phones
If I am at the connection sending more messages without s.close line in sendMessageToServer only one message is passing through. No error is displayed after it.
The message form runTcpConnection shows always (except when in this function is no SystemClock.sleep(10))
Hope it will help someone to diagnose my error.
As I see, you create a new socket whenever user click button send, right? I recommend you should init it only one time when user click connect, then you use it in send click event ( because this is TCP, you will disconnect to server if you create new instance of socket)
So, you should remove these lines in sendMessageToServer :
s = new Socket(serverIpAddress, SERVERPORT);
s.close();
and this line in runTcpConnection
s.close();
Socket should close whenever you don't want communicate with the server (onstop is an example, or when change activity...)
Also you should create only one instance of BufferedWriter too.
Hope this help.