質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

2回答

2717閲覧

pcをサーバーとし、androidをクライアントとしたソケット通信を行いたい。

wanwanteikoku

総合スコア13

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

1クリップ

投稿2018/11/15 09:24

編集2018/11/15 09:42

前提・実現したいこと

pcをサーバーとし、androidをクライアントとしたソケット通信を行いたい。

発生している問題・エラーメッセージ

pcでサーバーのプログラムを起動し待ち状態にした後に、クライアントとしたandroid studioを実行しているが、サーバー側で受信出来ないでいます。
内容としてはandroid studioでボタンを押すことで文字列を送った際に、サーバー側で偶数か奇数か判別するものになっており、今はクライアント側で「2」を送信しています。eclipseもandroid studioもエラーははかず実行できている状態です。
android studioではインターネット接続を行うパーミッションは追加してあります。
エラーが出ないためなぜサーバー側で受信できていないのか、もしくはクライアント側が送信できていないのか教えて頂けないでしょうか。よろしくお願い致します。
ソースコードは以下になります。

該当のソースコード

java(android

1//クライアント側 2import android.app.Activity; 3import android.util.Log; 4 5import java.io.BufferedReader; 6import java.io.IOException; 7import java.io.InputStreamReader; 8import java.io.PrintWriter; 9import java.net.Socket; 10 11class SocketConnection extends Activity { 12 13 void Connect(){ 14 15 Socket cSocket = null; 16 PrintWriter writer = null; 17 BufferedReader reader = null; 18 19 try{ 20 cSocket = new Socket(IPアドレス, ポート番号); 21 22 //送信 23 writer = new PrintWriter 24 (cSocket.getOutputStream(), true); 25 26 //受診 27 reader = new BufferedReader 28 (new InputStreamReader 29 (cSocket.getInputStream())); 30 31 while (true) { 32 writer.println("2"); 33 34 Log.d("test","サーバー側回答:" + reader.readLine()); 35 } 36 }catch(Exception e){ 37 e.printStackTrace(); 38 }finally{ 39 try { 40 if (reader != null) { 41 reader.close(); 42 } 43 if (writer != null) { 44 writer.close(); 45 } 46 if (cSocket != null) { 47 cSocket.close(); 48 } 49 } catch (IOException e) { 50 e.printStackTrace(); 51 } 52 System.out.println("終了"); 53 } 54 } 55} 56 57import android.os.Bundle; 58import android.support.v7.app.AppCompatActivity; 59import android.util.Log; 60import android.view.View; 61import android.widget.Button; 62 63public class MainActivity extends AppCompatActivity { 64 65 @Override 66 protected void onCreate(Bundle savedInstanceState) { 67 super.onCreate(savedInstanceState); 68 setContentView(R.layout.activity_main); 69 70 Button b1=findViewById(R.id.button); 71 b1.setOnClickListener(new View.OnClickListener() { 72 public void onClick(View view) { 73 SocketConnection s = new SocketConnection(); 74 s.Connect(); 75 } 76 }); 77 } 78}

java(eclipse)

1//サーバー側 2import java.io.BufferedReader; 3import java.io.IOException; 4import java.io.InputStreamReader; 5import java.io.PrintWriter; 6import java.net.InetSocketAddress; 7import java.net.ServerSocket; 8import java.net.Socket; 9 10class Socket_Connection { 11 12 13 void connect() throws Exception { 14 15 ServerSocket sSocket = null; 16 Socket socket = null; 17 BufferedReader reader = null; 18 PrintWriter writer = null; 19 20 try{ 21 //ソケットを作成 22 sSocket = new ServerSocket(); 23 sSocket.bind(new InetSocketAddress 24 (IPアドレス,ポート番号)); 25 26 System.out.println("入力待ち"); 27 28 socket = sSocket.accept(); 29 30 //受信 31 reader = new BufferedReader( 32 new InputStreamReader 33 (socket.getInputStream())); 34 35 //送信 36 writer = new PrintWriter( 37 socket.getOutputStream(), true); 38 39 String line = null; 40 int num; 41 while (true) { 42 43 line = reader.readLine(); 44 45 try{ 46 num = Integer.parseInt(line); 47 48 if(num%2==0){ 49 writer.println("OK"); 50 }else{ 51 writer.println("NG"); 52 } 53 }catch(NumberFormatException e){ 54 writer.println("偶数を入力して下さい"); 55 } 56 System.out.println("文字列=" + line); 57 } 58 }catch(Exception e){ 59 e.printStackTrace(); 60 }finally{ 61 try{ 62 if (reader!=null){ 63 reader.close(); 64 } 65 if (writer!=null){ 66 writer.close(); 67 } 68 if (socket!=null){ 69 socket.close(); 70 } 71 if (sSocket!=null){ 72 sSocket.close(); 73 } 74 System.out.println("サーバー側終了です"); 75 } catch (IOException e) { 76 e.printStackTrace(); 77 } 78 } 79 } 80} 81 82public class Main { 83 public static void main(String[] args) throws Exception{ 84 Socket_Connection sc =new Socket_Connection(); 85 sc.connect(); 86 } 87}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

euledge

2018/11/15 14:06

サーバーとAndroid Studioは同じPCで動いていませんよね? 同じポート番号では片方のソケット開けなくなります。
wanwanteikoku

2018/11/15 14:21

別のPCでおこなっております。
euledge

2018/11/15 14:30

WireSharkなどのパケット解析ツールで送受信されている様子を確認すると解決が早いかもです。
guest

回答2

0

コードに改めるべき点がいくらか見られますが、私が開発環境を動かせる状況にないため、細かいことを記すことができません。少し待っていただければ、検証したコードの例示付きで回答します。


遅くなりましたが、回答の詳細です。

まずサーバー側ですが、「ソケットを作成」というコメントの部分で、bind()の引数にIPアドレスを与えると接続を受け付けるネットワークを指定することになります。どこからでも受け付けるサーバーを作る場合、通常はポート番号を指定するだけです。ですから、

java

1 //ソケットを作成 2 sSocket = new ServerSocket(); 3 sSocket.bind(new InetSocketAddress(ポート番号));

のようにしましょう。

それから連続で待ち受けるように繰り返す区間ですが、この繰り返し方では正しく動作しないと思います。

java

1 while (true) { 2 socket = sSocket.accept();

のように、繰り返し開始をaccept()の前に持ってくるべきでしょう。

次にクライアント側ですが、前回のご質問での私の回答に誤りがあって、Android 3.0以降ではUIスレッド上でネットワーク接続を行うとNetworkOnMainThreadExceptionという例外が飛んで正常に動作しないという問題がありました。ですから、リンクを示したサンプルは現在のAndroid SDKでは動きません。大変申し訳ありませんでした。

正しく動くようにするには、その回答の末尾に書いた通りThreadやAsyncTaskといった別スレッド実装が必要です。記していただいたコードから修正するには、SocketConnectionクラスは

java

1class SocketConnection extends AsyncTask { 2 @Override 3 protected Void doInBackground(Void... voids) { 4 Connect(); 5 return null; 6 } 7 8 void Connect(){ 9 // ここは現状通り 10 } 11}

のようにAsyncTaskを継承するように改めて、これを呼び出すMainActivityでは

java

1 public void onClick(View view) { 2 SocketConnection s = new SocketConnection(); 3 s.execute(); 4 }

のようにすれば、SocketConnectionに記述したConnect()を非同期タスクとして動かすことができるでしょう。

また、Connect()の中でwhile文による永久ループを作っていますが、スレッドを永久に回す設計では正しく動作しません。このwhile文は除去して、一度のConnect()実行で一つのメッセージのやり取りのみを行う方向にしましょう。

java

1 //while (true) { 2 writer.println("2"); 3 4 Log.d("test","サーバー側回答:" + reader.readLine()); 5 //}

これだけ改修すれば、ボタンを1度押せば一つのメッセージの送受信を行えるようになるのではないかと思います。

投稿2018/11/20 15:29

編集2018/11/22 02:09
keicha_hrs

総合スコア6768

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

まずは、クライアントからサーバにpingがとおるかやってみることですね

投稿2018/11/16 00:41

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問