【Android】AndroidでSocket通信をする(クライアント編)

投稿者: | 2011年7月14日

以前にJavaSEでSocket通信のプログラムを書いた。今度は、AndroidでSocket通信をしてみる。
と言っても、コーディングはJavaSEとまったく同じやり方で出来るのだが、Androidの場合はSocket通信をするためにパーミッションを設定しておく必要がある。

まずは、AndroidManifest.xmlに以下のパーミッションを追記する。
<uses-permission android:name=”android.permission.INTERNET” />

次に、以下のような画面を作ってみた。

Sendボタンを押したときにサーバーと正しく接続できれば、テキストボックスに入力した値をサーバーへ送信するようになっている。
このレイアウトxmlのソースは以下のようになる。

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="120dp"
            android:layout_height="fill_parent"
            android:text="IP Address"
        />
        <EditText
            android:id="@+id/txtIPAdress"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:text=""
        />
    </LinearLayout>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="120dp"
            android:layout_height="fill_parent"
            android:text="Port"
        />
        <EditText
            android:id="@+id/txtPort"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:text="10000"
        />
    </LinearLayout>
    <EditText
            android:id="@+id/txtSend"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
    />
    <Button
        android:id="@+id/button1"
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Send" />
</LinearLayout>

Activity側のソースは以下のようになる。

MainActivity.java

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        findViewById(R.id.button1).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                String address = 
                    ((EditText)findViewById(R.id.txtIPAdress)).getText().toString();
                String strPort = 
                    ((EditText)findViewById(R.id.txtPort)).getText().toString();
                int port = Integer.parseInt(strPort);

                Socket socket = null;

                try {
                    socket = new Socket(address,port);
                    PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);

                    String sendTxt = 
                        ((EditText)findViewById(R.id.txtSend)).getText().toString();

                    pw.println(sendTxt);

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

                if( socket != null){
                    try {
                        socket.close();
                        socket = null;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
}

ボタンが押されたときにSocket通信の処理を書いているが、この部分は以前に作ったクライアントプログラムと全く変わっていない。
プログラムがビルドできたら、サーバーを立ち上げておこう。ここで使うサーバープログラムも、以前に作ったコンソールベースのものである。
サーバーが立ち上がったら、そのマシンのローカルIPアドレスを確認して、Android側のアドレス入力欄に入力する。
ローカルIPアドレスは、Windowsならばipconfigコマンドで確認できるだろう。
ポートの値はクライアントとサーバーで合っていれば良いが、ここでは例ということで「10000」固定にしておいた。

ipconfigで確認したIPアドレスを・・・

アプリのアドレス欄へ入力する

そうしたら、何か適当な文字を入力してSendボタンを押す。

正しく接続できたならば、サーバー側に受信した文字列が表示されるだろう。

実は、このAndroidプログラムはサーバーとの接続に失敗したり、接続に時間がかかったときに短時間画面をブロックしてしまい、使い勝手があまりよくない。
本来ならば、接続部分は別スレッドを起こすなりした方が良いだろう。

【Android】AndroidでSocket通信をする(クライアント編)」への2件のフィードバック

  1. きつね

    サンプルコードをコピーして試してみても、アプリが落ちます。
    以前のjava同士のやつは出来てるんですけど。。。

    返信
    1. keisuke

      非常にシンプルで分かりやすいサンプルがあって助かります!
      現在のandroidの仕様では送信部分は別のスレッドで行う必要があります.
      私もandroidでのTCP/IP通信の勉強を始めたばかりですが,修正して動作が確認できたソースを載せておきたいと思います.※ findViewById…の中身
      @Override
      public void onClick(View v) {
      Runnable sender = new Runnable() {
      @Override
      public void run() {
      String address =
      ((EditText) findViewById(R.id.txtIPAdress)).getText().toString();
      String strPort =
      ((EditText) findViewById(R.id.txtPort)).getText().toString();
      int port = Integer.parseInt(strPort);

      Socket socket = null;

      try {
      socket = new Socket(address, port);
      PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);

      String sendTxt =
      ((EditText) findViewById(R.id.txtSend)).getText().toString();

      pw.println(sendTxt);

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

      if (socket != null) {
      try {
      socket.close();
      socket = null;
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      }
      };
      Thread th = new Thread(sender);
      th.start();
      }

      返信

keisuke へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です