2017-10-24 11 views
0

こんにちはStackOverflowのコミュニティ、のJava +ラズベリーパイ+ ServerSocketを

私はラズベリーパイゼロにjava.net.ServerSocketを起動する具体的な質問があり、java.net.Socketとそれに接続します。 RPiはワイヤレスアクセスポイントとして設定されているので、複数のラップトップ/タブレットを使用してWLAN経由で接続することができます。目的は、RPiをサーバーとして(別のネットワークとデバイス上で動作するサーバーを必要とせずに)、一部のデバイスを(RPiに接続できる)クライアントとしてサーバー/クライアントゲームを起動することです。

  1. は私がタブレットでWLANを経由してRPIに接続:

    は、私は、彼らが常に同じ結果を示すことを証明するために、何度もすべての多くを、以下の4つの状況を試してみました。それから、そのタブレットでServerSocketを起動しました。その後、私はそのタブレットでSocketを起動し、それをServerSocketに接続しました。接続は機能し、データは双方向に送信されました。

  2. タブレットでWLAN経由でRPiに接続しました。それから、そのタブレットでServerSocketを起動しました。その後、私はRP0にソケットを立ち上げ、タブレット上で動作しているServerSocketに接続しました。接続は機能し、データは双方向に送信されました。

  3. タブレットでWLAN経由でRPiに接続しました。その後、RPiにServerSocket を公開しました。その後、私は自分のタブレットにSocketを起動し、RPi上で動作するServerSocketに接続しました。最初の奇妙なことは、ServerSocketのIPが0.0.0.0であり、クライアントがRPiに接続できなかったためにデータを送信できなかったという2番目の問題でした。

  4. タブレットでWLAN経由でRPiに接続しました。それから、RPiにServerSocket を立ち上げ、指定したIPアドレスにバインドします。その後、私は自分のタブレットでSocketを起動し、RPi上で動作するServerSocketに接続しました。 ServerSocketは指定されたIPアドレスにバインドできませんでした。したがって、Socketはサーバーに接続できませんでした。したがって、データは送信されませんでした。

ServerSocketに(0.0.0.0を除く)IPがバインドされていないのはなぜですか?なぜ私はIPアドレス0.0.0.0に接続できませんか? ServerSocketをRPi上でJavaで実行させるにはどうすればよいですか?ここで

は、私はすべての3つの状況のた​​めに使用されるJavaのソースコードです:

サーバー:

import java.net.ServerSocket; 
import java.net.InetAddress; 
import java.net.Socket; 
import java.net.InetSocketAddress; 

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 

public class Server { 
    private  ServerSocket ss; 

    public static void main(String[] args) { 
     new Server();  // call the constructor 
    } 

    public Server() { 
     try { 
      ss = new ServerSocket(4444); // create the ServerSocket 
      new Thread(new Runnable() {  // create new Thread for listening to new clients 
       public void run() { 
        startAccept();   // run the accept-clients method 
       } 
      }).start();  // don't forget to start the thread 
      System.out.println(InetAddress.getLocalHost().getHostAddress()); // print the IP-Address 
      System.out.println("4444");  // print the Port 
     } catch (Exception e) { 
      e.printStackTrace();  // show exceptions 
     } 
    } 

    public void startAccept() { 
     while (true) {  // listen to new clients 
      try { 
       Socket so = ss.accept(); // accept the clients and create reader/writer 
       BufferedReader bure = new BufferedReader(new InputStreamReader(so.getInputStream())); 
       BufferedWriter buwr = new BufferedWriter(new OutputStreamWriter(so.getOutputStream())); 
       new Thread(new Runnable() {  // start new thread for reading from the client 
        public void run() { 
         readSocket(bure, buwr); // run the read/write method of the client 
        } 
       }).start();  // don't forget to start the thread 
      } catch (Exception e) { 
       e.printStackTrace();  // show exceptions 
      } 
     } 
    } 

    public void readSocket(BufferedReader bure, BufferedWriter buwr) { 
     while (true) {  // listen to all messages sent by the client 
      try { 
       String l1 = bure.readLine();   // read first line 
       System.out.println("Rec1: <"+l1+">"); // show it 
       String l2 = bure.readLine();   // read second line 
       System.out.println("Rec2: <"+l2+">"); // show it 
       buwr.write(l1+" + "+l2+" = "+(Integer.parseInt(l1)+Integer.parseInt(l2))+"\n"); 
       buwr.flush();  // convert both lines to integers and send the sum of them 
      } catch (Exception e) { 
       e.printStackTrace();  // show exceptions 
      } 
     } 
    } 
} 

クライアント:

import java.net.InetAddress; 
import java.net.InetSocketAddress; 
import java.net.Socket; 

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 

public class Client { 
    public static void main(String[] args) {  // start the program 
     try { 
      Socket so = new Socket();  // create an unbound socket 
      so.connect(new InetSocketAddress("0.0.0.0", 4444), 10000); 
       // bind socket to the IP-address printed by the Server and create reader/writer 
      BufferedReader bure = new BufferedReader(new InputStreamReader(so.getInputStream())); 
      BufferedWriter buwr = new BufferedWriter(new OutputStreamWriter(so.getOutputStream())); 
      buwr.write("7\n4\n"); // send 7 and 4, both followed by a new line 
      buwr.flush(); 
      System.out.println("Sent: <7\n4\n>"); // show the user what has been sent 
      System.out.println("Message from Server: "+bure.readLine()); // sum sent by the server 
      so.close();  // close socket 
     } catch (Exception e) { 
      e.printStackTrace(); // show exception 
     } 
    } 
} 

が、私はこのトピック上の任意の助けを事前に感謝しています。

+1

「あなたは、そのタブレットでSocketを起動し、それをServerSocketに接続した」と言ったとき、どういう意味なのか分かりません。もっと詳しく説明できますか?ちなみに、 "0.0.0.0"は実際にはIP番号ではないという問題があると私は思っています。リスニング(サーバー)ソケットを作成して「すべてのインターフェイスでリッスン」を意味するときに使用されます。クライアントとして作成する場合は、実際のIP番号を使用する必要があります。 –

+0

「ソケットを起動する」とは、クライアントのソースコードをサーバーのIPで実行することを意味します。接続はJava内部で作成されます。サーバーのソースコードの「0.0.0.0」は単なる代表例です。 「ServerSocketを起動する」は、サーバーのソースコードを実行することを意味します。 –

+0

おそらく、単に代表的なコードではなく、実行した実際のコードを含んでいれば分かりやすいでしょうか?最初の質問で、「なぜIPアドレス0.0.0.0に接続できないのですか?」と言った。これはIPアドレス0.0.0.0への接続をしようとしているように見えますが、これは意味がありません。 –

答えて

0

最後に、自分で解決策を見つけました。

コアの問題は、thisチュートリアル(bridge-utilsでbrigdeをインストールしないで)を使ってRPiをWAPとしてセットアップすることでした。固定静的IPアドレスが定義されていない場合、RPIにアクセスすることはできないため、ServerSocketの任意の IPアドレスにバインドすることはできません。

sudo nano /etc/network/interfaces 

と、ファイル/ etc/network/interfacesを

を編集し、ファイルの末尾に次の行を記述します。

はRPI WAPがそのように動作しますし、静的IPアドレスを追加します。

auto wlan0 
iface wlan0 inet static 
    address 192.168.5.1 #Use own IP address here 
    netmask 255.255.255.0 

注:このファイルの末尾に空白行が必要です。静的IPアドレスが/etc/dnsmasq.confで定義された範囲内にある必要はありませんが、サブネットマスクが適合する場合(私の場合は192.168.5.xxx)のみ動作します。

次の問題は、どのIPにServerSocketがバインドされているかわかりませんでした。私は

System.out.println(InetAddress.getLocalHost().getHostAddress()); 
System.out.println(ss.getInetAddress().getHostAddress()); 

を呼び出すことによって、(コメントを参照してください)奇妙な出力を持って、ss.isBound()のクエリは、常にtrueを返し。この問題の解決策は、ServerSocketをRPiのinterfacesファイルに定義されている特定のIPアドレスにバインドすることです。代わりに

ss = new ServerSocket(4444); 

を呼び出すの私はそうServerSocketのは、私が定義された静的IPアドレスにバインドされ始め

ss = new ServerSocket(); 
ss.bind(new InetSocketAddress("192.168.5.1", 4444)); 

を使用しました。 これで、サーバーにメッセージを送信できました。メッセージが解析され、結果がクライアントに返されました。

関連する問題