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

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

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

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

サーバ

サーバは、 クライアントサーバモデルにおいてクライアントからの要求に対し 何らかのサービスを提供するプログラムを指す言葉です。 また、サーバーソフトウェアを稼動させているコンピュータ機器そのもののことも、 サーバーと呼ぶ場合もあります。

Android Studio

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

Q&A

解決済

2回答

3174閲覧

PC(サーバ役)とandroid端末(クライアント役)間で通信したい

Jhon_McClane

総合スコア48

Java

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

サーバ

サーバは、 クライアントサーバモデルにおいてクライアントからの要求に対し 何らかのサービスを提供するプログラムを指す言葉です。 また、サーバーソフトウェアを稼動させているコンピュータ機器そのもののことも、 サーバーと呼ぶ場合もあります。

Android Studio

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

0グッド

0クリップ

投稿2021/08/02 13:40

前提・実現したいこと

現在javaで,端末間でP2P通信が出来るようなリアルタイムコミュニケーションアプリ(公には出さないアプリ)を自作しています.
その際に,NAT越えなどに必要なSTUNサーバ,Singnalingサーバをpc側で担おうと考えています.
クライアント側の処理をandroid studio
サーバ側の処理をeclipseで書き,それぞれ実行しています.

しかしlogを見ると,クライアントによるパケット送信処理までは進むのですが,STUNサーバのsocket.receive.();まで届いていないため,その後のステップに処理が流れません.おそらく,端末とPC間で通信が出来ていないとは推測できるのですが,なぜできないのか,何の処理が不足しているのかが分かりません.

1つのpc上でクライアントとサーバを担うプログラムをそれぞれの起動すると動くのですが,クライアントの処理をandroid端末で実装すると通信が出来ません。

以下を設定

STUNサーバ      IP:"127.0.0.1",port:55554 Singnalingサーバ IP:"127.0.0.1",port:55555

可読性が良くないですが,コードを載せておきます.
(1) eclipse上で以下のSTUNサーバの受信クラスを実行しておきます.

import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UDPHolePunchingServerReceive extends Thread { DatagramSocket serverSocket; UDPHolePunchingServerReceiveListener udpHolePunchingServerReceiveListener; UDPHolePunchingServerReceive(DatagramSocket datagramSocket,UDPHolePunchingServerReceiveListener udpHolePunchingServerReceiveListener){ this.serverSocket = datagramSocket; // datagramSocket = new DatagramSocket(port) port = 55554 this.udpHolePunchingServerReceiveListener = udpHolePunchingServerReceiveListener; } public void run(){ if(serverSocket == null) { System.out.println( "socket is null"); } while(true) { // receive Data DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024); try { serverSocket.receive(receivePacket); // android studioの送信パケットが届かない String getMsg = new String(receivePacket.getData(), 0, receivePacket.getLength()); if(getMsg.equals("Hello")){ udpHolePunchingServerReceiveListener.onReceiveMsg(receivePacket); System.out.println("UDPHolePunchingReceive;getMsg:"+getMsg); }else{ System.out.println("UDPHolePunchingReceive;getMsg:"+getMsg); } } catch (IOException e) { System.out.println( "受信失敗"+e); } } } }

(2) android studioから以下のSTUNサーバへの送信クラスを実行します.

import android.os.AsyncTask; import android.util.Log; import com.example.g_lockonbyaw.main.UtilCommon; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class STUNServerClientSend extends AsyncTask<String, String, Integer> { private DatagramSocket socket; ISTUNServerClientSend iSendSTUNServerClient; //コンストラクタ STUNServerClientSend(DatagramSocket socket, ISTUNServerClientSend iSendSTUNServerClient){ this.socket = socket; this.iSendSTUNServerClient = iSendSTUNServerClient; } // 自端末からSTUN Serverへpingを送り続ける @Override protected Integer doInBackground(String... ttt) { String sendMsg = "Hello"; UtilCommon utilCommon = (UtilCommon) UtilCommon.getAppContext(); String stunServerIP = utilCommon.getStunServerIP(); // "127.0.0.1" int stunServerPort = utilCommon.getStunServerPort(); // 55554 while(true) { try{ byte[] sendData = sendMsg.getBytes(); DatagramPacket sendPacket = new DatagramPacket( sendData, sendData.length, InetAddress.getByName(stunServerIP), stunServerPort ); socket.send(sendPacket); //ping 送信 if(sendMsg.equals("Hello")){ sendMsg = "Ping"; iSendSTUNServerClient.onSentHelloMsgToStun(); } Log.d("STUNServerClientSender","doInBackgroundが呼ばれたよ"); sleep(); }catch (Exception e){ e.printStackTrace(); } } } private void sleep(){ try { Thread.sleep(60000); } catch (InterruptedException e) { e.printStackTrace(); } }

疑問

サーバについて実装したことがないため,詳しくないのですが,
通信を行う場合,「クライアントとサーバ側の最低2つの実行構成が必要である」という認識で合っていますか.
私は,この認識の基,クライアントの実装をandroid studioで,サーバ側の実装をeclipse上で実行しています.

補足情報(FW/ツールのバージョンなど)

android studio: 4.2
eclipse: Version: 2020-12 M1 (4.18.0 M1)

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

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

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

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

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

y_waiwai

2021/08/02 13:48

いまいち構成がよくわからんですが、 すべて同一PC上で走らせて通信できないってことなんでしょうか
jimbe

2021/08/02 14:38 編集

確か AndroidStudio で実機でテストする場合、localhost をパソコンとして認識させるような設定が必要だったような気がしますが・・・そんな設定をした覚えはあるのですが何のためだったかが思い出せません(><;;; つまり、パソコン上でサーバが動いていて、同じパソコン上でAndroidStudio でエミュレーダで動かすならサーバは localhost ですが、実機に入れて動かしたら localhost は(パソコンでは無く)実機になってしまうので、サーバのアドレスはちゃんとIPアドレスを指定しないといけないのでは・・・と、 String stunServerIP = utilCommon.getStunServerIP(); // "127.0.0.1" のコメントを見て思いました。
Jhon_McClane

2021/08/02 15:00

y_waiwai様 コメントありがとうございます。 実機にAndroidStudioでつくったアプリをインストールさせ実行し, pc(サーバ)と実機間で通信したいです。 実機とpcで通信するため,同一pc上ではないと私は考えていました(同一上になっているのかわからない)。。。
Jhon_McClane

2021/08/02 15:17 編集

jimbe様 コメントありがとうございます. そうすると,サーバをPCで代用しているため,pcのグローバルIPアドレスを指定する認識で合っていますでしょうか.
ishina_yum

2021/08/02 15:34

Android機とPCは通信できている状態なのでしょうか? たとえば「PC側で立ち上げたWebサーバーにAndroid機からアクセスすると、正常にWebページを表示できた」とかそういった確認はされていますか?
Jhon_McClane

2021/08/02 15:52 編集

ishina_yum様 コメントありがとうございます. 結論から言うと確認していません.互いに通信できていないと思われます。 サーバに強くないのですが,「PC側で立ち上げたWebサーバー」をすぐ作って確かめることは可能なのでしょうか。
jimbe

2021/08/02 17:02 編集

> pcのグローバルIPアドレス 実機がどう経由して PC に繋がるかによりますが… PC がインターネットに公開されていて 4G 等経由でインターネットから接続するのでしょうか。 それとも PC 繋がっている LAN に Wifi で繋がっているのでしょうか。 どちらにしても、その接続で使えるアドレスということになるでしょう。
Jhon_McClane

2021/08/02 16:51

>jimbe様 PC 繋がっている LAN に Wifi で繋がっている状況です。 ゆくゆくは、レンタルサーバを借りる予定なので、それを考えると、実機テストはまだまだ先でいい気がしてきました。
dodox86

2021/08/02 17:29

Androidのクライアントからサーバーに接続するときに、宛先サーバーのIPアドレスが > STUNサーバ      IP:"127.0.0.1",port:55554 > Singnalingサーバ IP:"127.0.0.1",port:55555 とかだったら、泣いても笑っても繋がりません。127.0.0.1はlocalhostへのループバックアドレスです。それと、以下の設定と確認は必須です。 https://developer.android.com/training/basics/network-ops/connecting?hl=ja
guest

回答2

0

ベストアンサー

不慣れでしたら、余計な部分を省いたもので確認しておくのも良いのではないでしょうか。

以下のコードで PC 側を動かした後 Android 側を動かしてボタンを押すと、Eclipse のコンソールは

plain

1受信 2Hello World! 3終了

となりました。
"192.168.1.6" は Eclipse (や AndroidStudio) の動いている PC の LAN 側アドレスです。
ちなみに実機は Wifi で LAN に繋がっており、LAN 内でのアドレスは 192.168.1.9 (DHCP 配布)です。

PC 側(Eclipse で作成・実行)
UdpServer.java

java

1import java.io.IOException; 2import java.net.DatagramPacket; 3import java.net.DatagramSocket; 4import java.net.SocketException; 5 6public class UdpServer { 7 public static void main(String[] args) throws SocketException, IOException { 8 byte[] buf = new byte[1024]; 9 10 DatagramPacket packet = new DatagramPacket(buf, buf.length); 11 try(DatagramSocket socket = new DatagramSocket(55554);) { 12 System.out.println("受信"); 13 socket.receive(packet); 14 int len = packet.getLength(); 15 System.out.println(new String(buf, 0, len)); 16 System.out.println("終了"); 17 } 18 } 19}

Android側(AndroidStudio で作成・エミュレータもしくは実機で実行)
MainActivity.java

java

1import androidx.appcompat.app.AppCompatActivity; 2 3import android.os.Bundle; 4import android.util.Log; 5import android.widget.Button; 6 7import java.io.IOException; 8import java.net.*; 9import java.nio.charset.StandardCharsets; 10 11public class MainActivity extends AppCompatActivity { 12 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.activity_main); 17 18 Button sendButton = findViewById(R.id.send); 19 sendButton.setOnClickListener(v -> { 20 new Thread(() -> { 21 byte[] data = "Hello World!".getBytes(StandardCharsets.UTF_8); 22 try { 23 InetAddress ip = InetAddress.getByName("192.168.1.6"); 24 DatagramPacket packet = new DatagramPacket(data, data.length, ip, 55554); 25 try(DatagramSocket socket = new DatagramSocket();) { 26 socket.send(packet); 27 Log.d("MainActivity","send"); 28 } catch(IOException e) { 29 e.printStackTrace(); 30 } 31 } catch(UnknownHostException | SecurityException e) { 32 e.printStackTrace(); 33 } 34 }).start(); 35 }); 36 } 37}

レイアウト
activity_main.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:app="http://schemas.android.com/apk/res-auto" 5 xmlns:tools="http://schemas.android.com/tools" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 tools:context=".MainActivity"> 9 10 <Button 11 android:id="@+id/send" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:text="Hello World!" 15 app:layout_constraintBottom_toBottomOf="parent" 16 app:layout_constraintLeft_toLeftOf="parent" 17 app:layout_constraintRight_toRightOf="parent" 18 app:layout_constraintTop_toTopOf="parent" /> 19 20</androidx.constraintlayout.widget.ConstraintLayout>

AndroidManifest.xml に追加

xml

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

投稿2021/08/02 19:05

編集2021/08/02 19:30
jimbe

総合スコア12543

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

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

Jhon_McClane

2021/08/03 05:24

jimbe様 解決することが出来ました。ありがとうございます。 やっと次のステップに進むことが出来ます。^^
guest

0

括弧書きですが、公には出さないアプリという仕様なのですね。
それでしたら、SoftEatherを使うと、簡単にNAT超えしてVPN構築できます。
面倒なコーディングとか抜きで、同一LANとしてプログラミングできますよ。Open Sourceですが、企業向けサービスも展開しているのでオススメです。

投稿2021/08/02 15:57

編集2021/08/03 08:08
ShortArrow

総合スコア141

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問