狠狠撸

狠狠撸Share a Scribd company logo
2013

ネットワーク第 5 回
目
HTTP 通信/ソケット通信
1.

Socket 通信を行うプログラム
ソケット通信を利用したチャットクライアント(Android アプリ)とサーバプログラム
を作成します。今回は、サーバは自分の PC 内に起動させます。

※Android Virtual Device(AVD)の設定
Eclipse からエミュレータでデバッグを行うために、エミュレータの端末の設定を追加しま
す。
Eclipse のメニューから[ウインドウ]->[AVD Manager]を選択し、
[New]ボタンをクリック。
以下のように設定してください。

ソースコード(クライアント側)
Eclipse を開いて、パッケージエクスプローラーで右クリックし、[新規]->[Android プ
ロジェクト]を選択します。
プロジェクト名は
「SocketEx」
としてください。
Target SDK
と Compile With は Android4.0(IceCreamSandwich)を選びます。ActivityName は
「SocketEx」としましょう。
package com.example.socketex;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
public class SocketEx extends Activity implements View.OnClickListener{
private final static String BR = System.getProperty("line.separator");
private final static int WC = LinearLayout.LayoutParams.WRAP_CONTENT;
private final static int MP = LinearLayout.LayoutParams.MATCH_PARENT;
private static final String ADDRESS = "192.168.1.100"; ※変更すること!
private TextViewlblReceive;
private EditTexteditText;
private Button btnSend;
private Socket socket;
private InputStream in;
private OutputStream out;
private boolean error;
private final Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
LinearLayout layout = new LinearLayout(this);
layout.setBackgroundColor(Color.rgb(255,255,255));
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);
editText = new EditText(this);
editText.setId(2);
editText.setText("", TextView.BufferType.NORMAL);
editText.setLayoutParams(new

LinearLayout.LayoutParams(MP,

WC));
layout.addView(editText);
btnSend = new Button(this);
btnSend.setText("送信");
btnSend.setOnClickListener(this);
btnSend.setLayoutParams(new

LinearLayout.LayoutParams(WC,

WC));
layout.addView(btnSend);
lblReceive = new TextView(this);
lblReceive.setId(1);
lblReceive.setText("");
lblReceive.setTextSize(16.0f);
lblReceive.setTextColor(Color.rgb(0, 0, 0));
lblReceive.setLayoutParams(new
WC));
layout.addView(lblReceive);

LinearLayout.LayoutParams(MP,
}
@Override
public void onStart() {
super.onStart();
Thread thread = new Thread() {
public void run() {
try {
connect(ADDRESS, 8080);
} catch (Exception e) {
}
}
};
thread.start();
}
@Override
public void onStop() {
super.onStop();
disconnect();
}
private void addText(final String text) {
handler.post(new Runnable() {
@Override
public void run() {
lblReceive.setText(text + BR + lblReceive.getText());
}
});
}
private void connect(String address, int port) {
int size;
String str;
byte[] w = new byte[1024];
try {
addText("接続中");
socket = new Socket(address, port);
in = socket.getInputStream();
out = socket.getOutputStream();
addText("接続完了");
while(socket != null &&socket.isConnected()) {
size = in.read(w);
if (size <= 0) {
continue;
}
str = new String(w, 0, size, "UTF-8");
addText(str);
}
} catch (Exception e) {
addText("通信に失敗しました。");
}
}
private void disconnect() {
try {
socket.close();
socket = null;
} catch (Exception e) {
}
}
@Override
public void onClick(View v) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
error = false;
try {
if (socket != null &&socket.isConnected()) {
byte[]

w

=

editText.getText().toString().getBytes("UTF8");
out.write(w);
out.flush();
}
} catch (Exception e) {
error = true;
}
handler.post(new Runnable() {
public void run() {
if (error) {
addText(" 通 信 に 失 敗 し ま
した");
} else {
editText.setText("",
TextView.BufferType.NORMAL);
}
}
});
}
});
thread.start();
}
}
ソースコード(サーバ側)
Eclipse で新規 Java プロジェクト『chatserver』を作成します。作成したら、src フォルダ
の直下に、
『ChatServer.java』
『CharServerThread.java』2 つの java ファイルを作成しま
す。ソースコードはそれぞれ以下のように記述します。
○ChatServer.java
package com.example;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* This class launches the web application in an embedded Jetty container.
* This is the entry point to your application. The Java command that is used for
* launching should fire this main method.
*
*/
public class ChatServer {
public void start(int port) {
ServerSocket server;
Socket socket;
ChatServerThread thread;
try {
server = new ServerSocket(port);
System.err.println("ChatServer start" +
"?nIP

Address:"

InetAddress.getLocalHost().getHostAddress()
+ "?nPort:" + port);
while (true) {
try {
socket = server.accept();
thread = new ChatServerThread(socket);
thread.start();
} catch (IOException e) {
System.out.println(e);
}

+
}
} catch (IOException e) {
System.err.println(e);
}
}
public static void main(String[] args) throws Exception{
ChatServer server = new ChatServer();
server.start(8080);
}
}
○ChatServerThread.java
package com.example;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class ChatServerThread extends Thread {
private

static

List<ChatServerThread>

ArrayList<ChatServerThread>();
private Socket socket;
public ChatServerThread(Socket socket) {
super();
this.socket = socket;
threads.add(this);
}

threads

=

new
public void run() {
InputStream in = null;
String message;
int size;
byte[] w = new byte[10240];
try {
System.err.println("ChatServerThread start");
in = socket.getInputStream();
while(true) {
try {
size = in.read(w);
if (size <= 0) {
throw new IOException();
}
message = new String(w, 0, size, "UTF8");
System.out.println(message);
sendMessageAll(message);
} catch(IOException e) {
System.out.println("ChatServerThread
stop");
socket.close();
threads.remove(this);
return;
}
}
} catch (IOException e) {
System.err.println(e);
}
}
public void sendMessageAll(String message) {
for (ChatServerThread thread : threads) {
if (thread.isAlive()) {
thread.sendMessage(this, message);
}
}
System.out.println(message);
}
public void sendMessage(ChatServerThread talker, String message) {
try {
OutputStream out = socket.getOutputStream();
byte[] w = message.getBytes("UTF8");
out.write(w);
out.flush();
} catch (IOException e) {
}
}
}
ソースを記述したら、Java アプリケーションとして実行してください。
その後、Android アプリを起動します。
2.

HTTP 通信を行う Android アプリ

HTTP 通信の GET/POST メソッドを行ってネット上の情報を表示するアプリを作成します。
ソースコード
Eclipse を開いて、パッケージエクスプローラーで右クリックし、[新規]->[Android プロジ
ェクト]を選択します。
プロジェクト名は
「HttpEx」
としてください。
Target SDK と Compile
With は Android4.0(IceCreamSandwich)を選びます。ActivityName は「HttpEx」としま
しょう。
プロジェクトが作成出来たら、src.com.example.httpex フォルダの HttpEx.java ファイル
を以下のように編集してください。
また、AndroidManifest.xml を開き、
『Permission』タブの中の Add ボタンをクリックし
て、
『User Permission』を選択します。Name は『android.permission.INTERNET』を選
択してください。
package com.example.httpex;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
public class HttpEx extends Activity implements View.OnClickListener{
private static final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;
private static final int MP = LinearLayout.LayoutParams.MATCH_PARENT;
private EditTexteditText;
// リクエスト先の URL
private static final String URL = "http://httpserverex.herokuapp.com/hello";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// レイアウトの生成
LinearLayout layout = new LinearLayout(this);
layout.setBackgroundColor(Color.rgb(255, 255, 255));
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);
// エディットテキストの生成
editText = new EditText(this);
editText.setText("", EditText.BufferType.NORMAL);
editText.setLayoutParams(new

LinearLayout.LayoutParams(MP,

WC));
layout.addView(editText);
layout.addView(makeButton("HTTP 通信", "read"));
}
/**
* ボタンの生成
* @param text
* @param tag
* @return
*/
private Button makeButton(String text, String tag) {
Button button = new Button(this);
button.setText(text);
button.setTag(tag);
button.setOnClickListener(this);
button.setLayoutParams(new

LinearLayout.LayoutParams(WC,

WC));
return button;
}
@Override
public void onClick(View arg0) {
String tag = (String) arg0.getTag();
if (tag.equals("read")) {
Thread thread = new Thread(new Runnable() {
String text = null;
@Override
public void run() {
// HTTP 通信
try {
text

=

String(httpToData(URL));
} catch (Exception e) {
text = null;
}
Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
if (text != null) {
editText.setText(text, TextView.BufferType.EDITABLE);
} else {
HttpEx.showDialog(HttpEx.this, "エラー", "読み込みに失敗しました");
}
}
});
}
});
thread.start();
}
}
public static byte[] httpToData(String path) throws Exception {
byte[] write = new byte[1024];
HttpURLConnection connection = null;
InputStream in = null;
ByteArrayOutputStream out = null;
try {
// HTTP 接続のオープン

new
URL url = new URL(path);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
in = connection.getInputStream();
out = new ByteArrayOutputStream();
int size;
while ((size = in.read(write)) > 0) {
out.write(write, 0, size);
}
out.close();
in.close();
connection.disconnect();
return out.toByteArray();
} catch (Exception e) {
try {
if (connection != null) {
connection.disconnect();
}
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
} catch (Exception e2) {
}
throw e;
}
}
private static void showDialog(Context context, String title, String text) {
AlertDialog.Builder ad = new AlertDialog.Builder(context);
ad.setTitle(title);
ad.setMessage(text);
ad.setPositiveButton("OK", null);
ad.show();
}
}
ソースが記述出来たら、Android Application として実行してください。
<演習>
GET リクエストで上記の URL にアクセスしていますが、POST 用のボタンを追加し、そ
のボタンをクリックされた場合は、POST リクエストを行うように修正しなさい。
また、リクエストクエリも追加で送信出来るように修正しなさい。

More Related Content

ネットワーク第5回

  • 1. 2013 ネットワーク第 5 回 目 HTTP 通信/ソケット通信
  • 2. 1. Socket 通信を行うプログラム ソケット通信を利用したチャットクライアント(Android アプリ)とサーバプログラム を作成します。今回は、サーバは自分の PC 内に起動させます。 ※Android Virtual Device(AVD)の設定 Eclipse からエミュレータでデバッグを行うために、エミュレータの端末の設定を追加しま す。 Eclipse のメニューから[ウインドウ]->[AVD Manager]を選択し、 [New]ボタンをクリック。 以下のように設定してください。 ソースコード(クライアント側) Eclipse を開いて、パッケージエクスプローラーで右クリックし、[新規]->[Android プ
  • 3. ロジェクト]を選択します。 プロジェクト名は 「SocketEx」 としてください。 Target SDK と Compile With は Android4.0(IceCreamSandwich)を選びます。ActivityName は 「SocketEx」としましょう。 package com.example.socketex; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.view.Window; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; public class SocketEx extends Activity implements View.OnClickListener{ private final static String BR = System.getProperty("line.separator"); private final static int WC = LinearLayout.LayoutParams.WRAP_CONTENT; private final static int MP = LinearLayout.LayoutParams.MATCH_PARENT; private static final String ADDRESS = "192.168.1.100"; ※変更すること! private TextViewlblReceive; private EditTexteditText; private Button btnSend; private Socket socket; private InputStream in; private OutputStream out; private boolean error;
  • 4. private final Handler handler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); LinearLayout layout = new LinearLayout(this); layout.setBackgroundColor(Color.rgb(255,255,255)); layout.setOrientation(LinearLayout.VERTICAL); setContentView(layout); editText = new EditText(this); editText.setId(2); editText.setText("", TextView.BufferType.NORMAL); editText.setLayoutParams(new LinearLayout.LayoutParams(MP, WC)); layout.addView(editText); btnSend = new Button(this); btnSend.setText("送信"); btnSend.setOnClickListener(this); btnSend.setLayoutParams(new LinearLayout.LayoutParams(WC, WC)); layout.addView(btnSend); lblReceive = new TextView(this); lblReceive.setId(1); lblReceive.setText(""); lblReceive.setTextSize(16.0f); lblReceive.setTextColor(Color.rgb(0, 0, 0)); lblReceive.setLayoutParams(new WC)); layout.addView(lblReceive); LinearLayout.LayoutParams(MP,
  • 5. } @Override public void onStart() { super.onStart(); Thread thread = new Thread() { public void run() { try { connect(ADDRESS, 8080); } catch (Exception e) { } } }; thread.start(); } @Override public void onStop() { super.onStop(); disconnect(); } private void addText(final String text) { handler.post(new Runnable() { @Override public void run() { lblReceive.setText(text + BR + lblReceive.getText()); } }); } private void connect(String address, int port) { int size; String str;
  • 6. byte[] w = new byte[1024]; try { addText("接続中"); socket = new Socket(address, port); in = socket.getInputStream(); out = socket.getOutputStream(); addText("接続完了"); while(socket != null &&socket.isConnected()) { size = in.read(w); if (size <= 0) { continue; } str = new String(w, 0, size, "UTF-8"); addText(str); } } catch (Exception e) { addText("通信に失敗しました。"); } } private void disconnect() { try { socket.close(); socket = null; } catch (Exception e) { } } @Override public void onClick(View v) { Thread thread = new Thread(new Runnable() { @Override
  • 7. public void run() { error = false; try { if (socket != null &&socket.isConnected()) { byte[] w = editText.getText().toString().getBytes("UTF8"); out.write(w); out.flush(); } } catch (Exception e) { error = true; } handler.post(new Runnable() { public void run() { if (error) { addText(" 通 信 に 失 敗 し ま した"); } else { editText.setText("", TextView.BufferType.NORMAL); } } }); } }); thread.start(); } } ソースコード(サーバ側) Eclipse で新規 Java プロジェクト『chatserver』を作成します。作成したら、src フォルダ の直下に、 『ChatServer.java』 『CharServerThread.java』2 つの java ファイルを作成しま す。ソースコードはそれぞれ以下のように記述します。 ○ChatServer.java
  • 8. package com.example; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; /** * * This class launches the web application in an embedded Jetty container. * This is the entry point to your application. The Java command that is used for * launching should fire this main method. * */ public class ChatServer { public void start(int port) { ServerSocket server; Socket socket; ChatServerThread thread; try { server = new ServerSocket(port); System.err.println("ChatServer start" + "?nIP Address:" InetAddress.getLocalHost().getHostAddress() + "?nPort:" + port); while (true) { try { socket = server.accept(); thread = new ChatServerThread(socket); thread.start(); } catch (IOException e) { System.out.println(e); } +
  • 9. } } catch (IOException e) { System.err.println(e); } } public static void main(String[] args) throws Exception{ ChatServer server = new ChatServer(); server.start(8080); } } ○ChatServerThread.java package com.example; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.ArrayList; import java.util.List; public class ChatServerThread extends Thread { private static List<ChatServerThread> ArrayList<ChatServerThread>(); private Socket socket; public ChatServerThread(Socket socket) { super(); this.socket = socket; threads.add(this); } threads = new
  • 10. public void run() { InputStream in = null; String message; int size; byte[] w = new byte[10240]; try { System.err.println("ChatServerThread start"); in = socket.getInputStream(); while(true) { try { size = in.read(w); if (size <= 0) { throw new IOException(); } message = new String(w, 0, size, "UTF8"); System.out.println(message); sendMessageAll(message); } catch(IOException e) { System.out.println("ChatServerThread stop"); socket.close(); threads.remove(this); return; } } } catch (IOException e) { System.err.println(e); } } public void sendMessageAll(String message) { for (ChatServerThread thread : threads) {
  • 11. if (thread.isAlive()) { thread.sendMessage(this, message); } } System.out.println(message); } public void sendMessage(ChatServerThread talker, String message) { try { OutputStream out = socket.getOutputStream(); byte[] w = message.getBytes("UTF8"); out.write(w); out.flush(); } catch (IOException e) { } } } ソースを記述したら、Java アプリケーションとして実行してください。 その後、Android アプリを起動します。 2. HTTP 通信を行う Android アプリ HTTP 通信の GET/POST メソッドを行ってネット上の情報を表示するアプリを作成します。 ソースコード Eclipse を開いて、パッケージエクスプローラーで右クリックし、[新規]->[Android プロジ ェクト]を選択します。 プロジェクト名は 「HttpEx」 としてください。 Target SDK と Compile With は Android4.0(IceCreamSandwich)を選びます。ActivityName は「HttpEx」としま しょう。 プロジェクトが作成出来たら、src.com.example.httpex フォルダの HttpEx.java ファイル を以下のように編集してください。 また、AndroidManifest.xml を開き、 『Permission』タブの中の Add ボタンをクリックし て、 『User Permission』を選択します。Name は『android.permission.INTERNET』を選 択してください。 package com.example.httpex;
  • 12. import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.view.Window; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; public class HttpEx extends Activity implements View.OnClickListener{ private static final int WC = LinearLayout.LayoutParams.WRAP_CONTENT; private static final int MP = LinearLayout.LayoutParams.MATCH_PARENT; private EditTexteditText; // リクエスト先の URL private static final String URL = "http://httpserverex.herokuapp.com/hello"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); // レイアウトの生成 LinearLayout layout = new LinearLayout(this); layout.setBackgroundColor(Color.rgb(255, 255, 255));
  • 13. layout.setOrientation(LinearLayout.VERTICAL); setContentView(layout); // エディットテキストの生成 editText = new EditText(this); editText.setText("", EditText.BufferType.NORMAL); editText.setLayoutParams(new LinearLayout.LayoutParams(MP, WC)); layout.addView(editText); layout.addView(makeButton("HTTP 通信", "read")); } /** * ボタンの生成 * @param text * @param tag * @return */ private Button makeButton(String text, String tag) { Button button = new Button(this); button.setText(text); button.setTag(tag); button.setOnClickListener(this); button.setLayoutParams(new LinearLayout.LayoutParams(WC, WC)); return button; } @Override public void onClick(View arg0) { String tag = (String) arg0.getTag(); if (tag.equals("read")) { Thread thread = new Thread(new Runnable() { String text = null;
  • 14. @Override public void run() { // HTTP 通信 try { text = String(httpToData(URL)); } catch (Exception e) { text = null; } Handler handler = new Handler(); handler.post(new Runnable() { @Override public void run() { if (text != null) { editText.setText(text, TextView.BufferType.EDITABLE); } else { HttpEx.showDialog(HttpEx.this, "エラー", "読み込みに失敗しました"); } } }); } }); thread.start(); } } public static byte[] httpToData(String path) throws Exception { byte[] write = new byte[1024]; HttpURLConnection connection = null; InputStream in = null; ByteArrayOutputStream out = null; try { // HTTP 接続のオープン new
  • 15. URL url = new URL(path); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.connect(); in = connection.getInputStream(); out = new ByteArrayOutputStream(); int size; while ((size = in.read(write)) > 0) { out.write(write, 0, size); } out.close(); in.close(); connection.disconnect(); return out.toByteArray(); } catch (Exception e) { try { if (connection != null) { connection.disconnect(); } if (in != null) { in.close(); } if (out != null) { out.close(); } } catch (Exception e2) { } throw e; } } private static void showDialog(Context context, String title, String text) { AlertDialog.Builder ad = new AlertDialog.Builder(context); ad.setTitle(title);
  • 16. ad.setMessage(text); ad.setPositiveButton("OK", null); ad.show(); } } ソースが記述出来たら、Android Application として実行してください。 <演習> GET リクエストで上記の URL にアクセスしていますが、POST 用のボタンを追加し、そ のボタンをクリックされた場合は、POST リクエストを行うように修正しなさい。 また、リクエストクエリも追加で送信出来るように修正しなさい。