Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to use Socket, ObjectInputStream and ObjectOutputStream in Android?
    text
    copied!<p>EDIT: While marked as a duplicate my situation is not the same as the other. I have discovered that serialized objects require the same package name on both the input and output streams. Mismatching package names was my problem. </p> <p>I have a Java server and client. They are able to connect through sockets and use ObjectInputStream and ObjectOutputStream to send the object Packet back and forth. I have attempted to implement the client in Android. The Android client connects but I am unable to use the streams.</p> <p>With my current implementation my Android client must be on the same network as my PC with the server running. My PC also has a static IP of 192.168.1.3. The error I get is </p> <blockquote> <p>java.io.StreamCorruptedException: invalid type code: AC. </p> </blockquote> <p>I'd post the code for my desktop server and client but I run out of characters. I got the code from <a href="http://www.dreamincode.net/forums/topic/259777-a-simple-chat-program-with-clientserver-gui-optional/" rel="nofollow">here</a>. I've modified that code so when the client connects no string is required. A user sends a ChatMessage (or Packet as I've renamed it) and the message contents are stored with the ClientThread. The client is able to request the last message they sent and the server returns it.</p> <p>How do I correctly use the object streams with the Android client?</p> <p>MainActivity:</p> <pre><code>package com.example.androidclient; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity { Button btnGetLastMessage, btnSend, btnLogout; TextView textStatus; EditText textMessage; NetworkTask networktask; private Socket nsocket; // Network Socket private ObjectInputStream nis; // Network Input Stream private ObjectOutputStream nos; // Network Output Stream @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnGetLastMessage = (Button) findViewById(R.id.btnGetLastMessage); btnSend = (Button) findViewById(R.id.btnSend); btnLogout = (Button) findViewById(R.id.btnLogout); textStatus = (TextView) findViewById(R.id.textStatus); textMessage = (EditText) findViewById(R.id.textMessage); btnGetLastMessage.setOnClickListener(btnGetLastMessageListener); btnSend.setOnClickListener(btnSendListener); btnLogout.setOnClickListener(btnLogoutListener); networktask = new NetworkTask(); networktask.execute(); } private OnClickListener btnLogoutListener = new OnClickListener() { public void onClick(View v) { networktask.SendDataToNetwork(new Packet( Packet.GET_LAST_MESSAGE)); } }; private OnClickListener btnGetLastMessageListener = new OnClickListener() { public void onClick(View v) { Packet msg = new Packet(Packet.GET_LAST_MESSAGE); networktask.SendDataToNetwork(msg); } }; private OnClickListener btnSendListener = new OnClickListener() { public void onClick(View v) { textStatus.setText("Sending Message to AsyncTask."); Packet msg = new Packet(Packet.SEND_MESSAGE, textMessage.getText().toString()); networktask.SendDataToNetwork(msg); } }; public class NetworkTask extends AsyncTask&lt;Void, byte[], Boolean&gt; { @Override protected void onPreExecute() { Log.i("AsyncTask", "onPreExecute"); } @Override protected Boolean doInBackground(Void... params) { // This runs on a // different thread boolean result = false; try { Log.i("AsyncTask", "doInBackground: Creating socket"); SocketAddress sockaddr = new InetSocketAddress("192.168.1.3", 15000); nsocket = new Socket(); nsocket.connect(sockaddr); // 10 second connection timeout if (nsocket.isConnected()) { // Creating both Data Stream try { nis = new ObjectInputStream(nsocket.getInputStream()); nos = new ObjectOutputStream(nsocket.getOutputStream()); } catch (IOException eIO) { Log.i("AsyncTask", "doInBackground: Exception creating new Input/output Streams: " + eIO); eIO.printStackTrace(); return false; } // creates the Thread to listen from the server Log.i("AsyncTask", "doInBackground: Socket created, streams assigned, listening from server"); while (true) { Log.i("AsyncTask", "doInBackground: Waiting for data from the server..."); try { Packet messageFromServer = (Packet) nis .readObject(); Log.i("ListenFromServer", "messageFromServer: " + messageFromServer.getMessage()); textStatus.setText("Last message: " + messageFromServer.getMessage()); } catch (IOException e) { Log.i("ListenFromServer", "Server has close the connection: " + e); e.printStackTrace(); break; } catch (ClassNotFoundException e2) { // Do nothing } catch (Exception e) { Log.i("ListenFromServer", "Generic exception: " + e); e.printStackTrace(); break; } } } } catch (IOException e) { Log.i("AsyncTask", "doInBackground: IOException"); e.printStackTrace(); result = true; } catch (Exception e) { Log.i("AsyncTask", "doInBackground: Exception"); e.printStackTrace(); result = true; } finally { try { nis.close(); nos.close(); nsocket.close(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } Log.i("AsyncTask", "doInBackground: Finished"); } return result; } public void disconnect() { try { nis.close(); nos.close(); nsocket.close(); } catch (Exception e) { Log.i("AsyncTask", "disconnect: Exception: " + e); e.printStackTrace(); } } public void SendDataToNetwork(Packet msg) { // You run this from // the // main thread. try { if (nsocket.isConnected()) { Log.i("AsyncTask", "SendDataToNetwork: Writing received message to socket"); try { nos.writeObject(msg); nos.flush(); } catch (IOException eIO) { Log.i("AsyncTask", "doInBackground: Exception during login: " + eIO); eIO.printStackTrace(); nis.close(); nos.close(); nsocket.close(); } } else { Log.i("AsyncTask", "SendDataToNetwork: Cannot send message. Socket is closed"); } } catch (Exception e) { Log.i("AsyncTask", "SendDataToNetwork: Message send failed. Caught an exception"); e.printStackTrace(); } } @Override protected void onProgressUpdate(byte[]... values) { if (values.length &gt; 0) { Log.i("AsyncTask", "onProgressUpdate: " + values[0].length + " bytes received."); textStatus.setText(new String(values[0])); } } @Override protected void onCancelled() { Log.i("AsyncTask", "Cancelled."); } @Override protected void onPostExecute(Boolean result) { if (result) { Log.i("AsyncTask", "onPostExecute: Completed with an Error."); textStatus.setText("There was a connection error."); } else { Log.i("AsyncTask", "onPostExecute: Completed."); } } } @Override protected void onDestroy() { super.onDestroy(); networktask.cancel(true); // In case the task is currently running } } </code></pre> <p>activity_layout:</p> <pre><code>&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" &gt; &lt;EditText android:id="@+id/textMessage" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="text" android:textSize="24sp" /&gt; &lt;Button android:id="@+id/btnSend" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send Message" &gt; &lt;/Button&gt; &lt;Button android:id="@+id/btnGetLastMessage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Get Last Message" &gt; &lt;/Button&gt; &lt;Button android:id="@+id/btnLogout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Logout" &gt; &lt;/Button&gt; &lt;TextView android:id="@+id/textStatus" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Status Goes Here" android:textSize="24sp" /&gt; &lt;/LinearLayout&gt; </code></pre> <p>android manifest:</p> <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.androidclient" android:versionCode="1" android:versionName="1.0" &gt; &lt;uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /&gt; &lt;uses-permission android:name="android.permission.INTERNET" &gt; &lt;/uses-permission&gt; &lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" &gt; &lt;/uses-permission&gt; &lt;application android:allowBackup="true" android:debuggable="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" &gt; &lt;activity android:name="com.example.androidclient.MainActivity" android:label="@string/app_name" &gt; &lt;intent-filter&gt; &lt;action android:name="android.intent.action.MAIN" /&gt; &lt;category android:name="android.intent.category.LAUNCHER" /&gt; &lt;/intent-filter&gt; &lt;/activity&gt; &lt;/application&gt; &lt;/manifest&gt; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload