2016年6月24日 星期五



Create the main layout of the Server Application


main.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="" >
    </TextView>

</LinearLayout>


Set up the Appropriate permission on AndroidManifest.xml


Add these following line to AndroidManifest.xml

=========================================================
<uses-permission android:name="android.permission.INTERNET" >
</uses-permission>

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
</uses-permission>

============================================================


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javacodegeeks.android.androidsocketserver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.INTERNET" >
    </uses-permission>

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
    </uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.javacodegeeks.android.androidsocketserver.Server"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Main Server Activity


Serva.java

package com.javacodegeeks.android.androidsocketserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;

public class Server extends Activity {

 private ServerSocket serverSocket;

 Handler updateConversationHandler;

 Thread serverThread = null;

 private TextView text;

 public static final int SERVERPORT = 6000;

 @Override
 public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  text = (TextView) findViewById(R.id.text2);

  updateConversationHandler = new Handler();

  this.serverThread = new Thread(new ServerThread());
  this.serverThread.start();

 }

 @Override
 protected void onStop() {
  super.onStop();
  try {
   serverSocket.close();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 class ServerThread implements Runnable {

  public void run() {
   Socket socket = null;
   try {
    serverSocket = new ServerSocket(SERVERPORT);
   } catch (IOException e) {
    e.printStackTrace();
   }
   while (!Thread.currentThread().isInterrupted()) {

    try {

     socket = serverSocket.accept();

     CommunicationThread commThread = new CommunicationThread(socket);
     new Thread(commThread).start();

    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }
 }

 class CommunicationThread implements Runnable {

  private Socket clientSocket;

  private BufferedReader input;

  public CommunicationThread(Socket clientSocket) {

   this.clientSocket = clientSocket;

   try {

    this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));

   } catch (IOException e) {
    e.printStackTrace();
   }
  }

  public void run() {

   while (!Thread.currentThread().isInterrupted()) {

    try {

     String read = input.readLine();

     updateConversationHandler.post(new updateUIThread(read));

    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }

 }

 class updateUIThread implements Runnable {
  private String msg;

  public updateUIThread(String str) {
   this.msg = str;
  }

  @Override
  public void run() {
   text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
  }
 }
}

Code for the Client project

Go ahead and create a new Android Application project, as you did with the Server Application. And paste the following code snippets in the respective files:

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="" >
    </TextView>

</LinearLayout>

Set up the Appropriate permission on AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javacodegeeks.android.androidsocketserver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.INTERNET" >
    </uses-permission>

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
    </uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.javacodegeeks.android.androidsocketserver.Server"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


Client.java

package com.javacodegeeks.android.androidsocketclient;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

public class Client extends Activity {

 private Socket socket;

 private static final int SERVERPORT = 5000;
 private static final String SERVER_IP = "10.0.2.2";

 @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();
   }

  }

 }
}

6. Port Forwarding

In order to interconnect the programs in the two different emulators this is what happens:
  1. The Server program will open the port 6000 on emulator A. That means that porst 6000 is open on the ip of the emulator which is 10.0.2.15.
  2. Now, the client in emulator B will connect to the locahost, that is the development machine, which is aliased at 10.0.2.2 at port 5000.
  3. The development machine (localhost) will forward the packets to 10.0.2.15 : 6000
Now, as you can see in the Window bar, we can access the cosnole of this emulator at localhost : 5554. Press  Windows Button + R, write cmd on the text box to open a comman line. In order to connect to the emulator you have to do :



1telnet localhost 5554


To perform the port forwarding write:
1redir add tcp:5000:6000

So now the packet will go through this direction : Emulator B -> development machine at 10.0.2.2 : 5000  -> Emulator A at 10.0.2.15 : 6000.
Ref : https://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/

沒有留言:

張貼留言