Socketクラスを使用してソケット通信をする


今回はJavaのSocketクラスを使用してサーバーとソケット通信する方法を紹介します。

詳細は以下から。

・Socketクラス

SocketクラスはAndroidライブラリーではなく、Javaの標準ライブラリーに入っています。

このクラスではソケット通信に関する様々な接続方法が実装されていますが、今回は

Socket(String host, int port)で宣言されているコンストラクタを使用します。

このコンストラクタの引数の詳細は以下。

host 接続先のホスト名を指定します
port 接続先のポート番号を指定します

このコンストラクタは、接続先のホスト名とポート番号を指定してオブジェクトを作成するだけで、接続まで行ってくれる便利なクラスです。

・InputStreamReaderクラスとBufferedReaderクラス

サーバーからのメッセージを取得するのにInputStreamReaderクラスとBufferedReaderクラスを使用します。

InputStreamReaderクラスはサーバーから送信されてくるバイトデータを文字データに変換してくれるクラスです。

BufferedReaderクラスはデータをバッファリングしてくれるクラスです。

この二つのクラスを以下のように使用することで効率的なデータ受信をサポートしてくれます。

BufferedReader in =<br>    new BufferedReader(new InputStreamReader("データ入力用ストリーム"));

・パーミッションの追加

ソケット通信ではインターネット接続を行うので、パーミッションにandroid.permission.INTERNETを追加する必要があります。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="org.jpn.techbooster.SocketSample"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".SocketSample"
                  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>

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

・サンプルコード

具体的な実装例を以下のサンプルコードで紹介します。今回はYahooのメールサーバーへ接続しています。

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

		Button btn = (Button) findViewById(R.id.Button01);
		btn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				connect();
			}
		});
	}

	private void connect() {
		TextView tv = (TextView) findViewById(R.id.TextView01);
		Socket connection = null;
		BufferedReader reader = null;
		try {
			// サーバーへ接続
			connection = new Socket("pop.mail.yahoo.co.jp", 110);

			// メッセージ取得オブジェクトのインスタンス化
			reader = new BufferedReader(new InputStreamReader(connection
					.getInputStream()));

			// サーバーからのメッセージを受信
			String message = reader.readLine();

			// 接続確認
			if (!(message.matches("^\\+OK.*$"))) {
				tv.setText("サーバーからのメッセージ:" + message);
				Toast.makeText(this, "サーバーとの接続に失敗しました。",
                                Toast.LENGTH_SHORT).show();
			} else {
				tv.setText("サーバーからのメッセージ:" + message);
				Toast.makeText(this, "サーバーとの接続に成功しました。",
                                Toast.LENGTH_SHORT).show();
			}

		} catch (UnknownHostException e) {
			e.printStackTrace();
			tv.setText("エラー内容:" + e.toString());
			Toast.makeText(this, "サーバーとの接続に失敗しました。",
                        Toast.LENGTH_SHORT).show();
		} catch (IOException e) {
			e.printStackTrace();
			tv.setText("エラー内容:" + e.toString());
			Toast.makeText(this, "サーバーとの接続に失敗しました。",
                        Toast.LENGTH_SHORT).show();
		} finally {
			try {
				// 接続終了処理
				reader.close();
				connection.close();
			} catch (IOException e) {
				e.printStackTrace();
				tv.setText("エラー内容:" + e.toString());
				Toast.makeText(this, "サーバーとの接続に失敗しました。",
                                Toast.LENGTH_SHORT).show();
			}
		}
	}
}

24行目ではYahooのメールサーバーのホスト名とポート番号を使用して接続しています。

27、28行目では接続が確立したSocketクラスの入力ストリームを使用してBufferedReaderクラスのオブジェクトを作成しています。

31行目ではBufferedReaderクラスのreadLine()メソッドを使用してサーバーからのメッセージを取得しています。

34~42行目はYahooメールサーバーから接続完了した旨のメッセージが返ってきているかを判定しています。今回接続しているYahooメールサーバーはPOP3サーバーなので、要求が正しく実行されるとメッセージの先頭に”+OK”が付加されます。

57、58行目ではサーバーとの接続を切断しています。不要になった接続は不要になった段階で切断しておかないと、他の通信処理に悪影響がでる可能性があるので、忘れないように適時切断して下さい。

5 Comments