2013-10-23 97 views
10

データをUDPソケット経由で正しく送信できますが、データを受信すると、受信コマンドで待機しています。何が原因なのかわかりません。 私のコードでUDPソケットでデータを送受信します。android

私は、サーバー側でアンドロイドデバイスから適切にデータを受け取ることができますが、サーバー側からアンドロイドデバイスにデータを送信すると受信しません。私はそれが受信サーバから他のクライアントなどのPCアプリケーションにデータを送信し、データが表示されたときにはなくrpoperly

class Task implements Runnable { 
    @Override 
    public void run() { 
     try { 
      String messageStr = "feed"; 
      int server_port = 8888; 
      InetAddress local = InetAddress.getByName("10.0.2.2"); 
      int msg_length = messageStr.length(); 
      byte[] message = messageStr.getBytes(); 


      DatagramSocket s = new DatagramSocket(); 
      // 

      DatagramPacket p = new DatagramPacket(message, msg_length, local, server_port); 
      s.send(p);//properly able to send data. i receive data to server 

      for (int i = 0; i <= 20; i++) { 
       final int value = i; 
       message = new byte[30000]; 
       p = new DatagramPacket(message,message.length); 
       s.receive(p); //keeps on waiting here but i am sending data back from server, but it never receives 
       final byte[] data = p.getData();; 
       try { 



        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         progressBar.setProgress(value); 
         imageView.setImageBitmap(BitmapFactory.decodeByteArray(data,0,data.length)); 
        } 
       }); 
      } 
     } 
     catch(Exception ex) 
     { 

     } 
    } 
} 
+0

私は、これは今少し古いですけど、あなたは、このいずれかを把握しましたか?あなたと同じ問題で立ち往生してください。私はサーバーにデータを取得していますが、何も返信しません。 – patrickdamery

+1

UDPの場合は、送信ごとにデータサイズを小さくしてみてください。これが私の問題を解決しました。 – user2539602

+0

私はしばらくしてそれを理解しましたが、データのサイズは送信側と受信側の両方で同じでなければなりません。そうでなければ、不安定な音声が得られます – patrickdamery

答えて

21

Eclipseのドキュメント:

はこのソケットと引数パックに保存するからパケットを受信します。 パックのすべてのフィールドは、受信したデータに従って設定する必要があります。 受信データがパケットバッファサイズよりも長い場合は、切り捨てられます。 このメソッドは、パケットが受信されるか、またはタイムアウトが になるまでブロックします。

s.receive(p);」コマンドブロックスレッドはデータをreceicesまたはsetSoTimeout(タイムアウト)で設定されたタイムアウトが終わるまで。

私はコミュニケーションを実現するために2つのクラスを作っています。 まずUDP-サーバー:

import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import android.annotation.SuppressLint; 
import android.content.Intent; 
import android.os.AsyncTask; 
import android.os.Build; 

public class UDP_Server 
{ 
    private AsyncTask<Void, Void, Void> async; 
    private boolean Server_aktiv = true; 

    @SuppressLint("NewApi") 
    public void runUdpServer() 
    { 
     async = new AsyncTask<Void, Void, Void>() 
     { 
      @Override 
      protected Void doInBackground(Void... params) 
      { 
       byte[] lMsg = new byte[4096]; 
       DatagramPacket dp = new DatagramPacket(lMsg, lMsg.length); 
       DatagramSocket ds = null; 

       try 
       { 
        ds = new DatagramSocket(Main.SERVER_PORT); 

        while(Server_aktiv) 
        { 
         ds.receive(dp); 

         Intent i = new Intent(); 
         i.setAction(Main.MESSAGE_RECEIVED); 
         i.putExtra(Main.MESSAGE_STRING, new String(lMsg, 0, dp.getLength())); 
         Main.MainContext.getApplicationContext().sendBroadcast(i); 
        } 
       } 
       catch (Exception e) 
       { 
        e.printStackTrace(); 
       } 
       finally 
       { 
        if (ds != null) 
        { 
         ds.close(); 
        } 
       } 

       return null; 
      } 
     }; 

     if (Build.VERSION.SDK_INT >= 11) async.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
     else async.execute(); 
    } 

    public void stop_UDP_Server() 
    { 
     Server_aktiv = false; 
    } 
} 

私はBroadcastReceiverに受信したデータを送信し、そこにあなたがデータとしたいこれまでに何ができます。

そして今私のクライアントはデータを送信します。このコードではブロードキャストを送信しますが、直接IPなどに送信するコードを変更することは問題ありません。

import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import android.annotation.SuppressLint; 
import android.os.AsyncTask; 
import android.os.Build; 

public class UDP_Client 
{ 
    private AsyncTask<Void, Void, Void> async_cient; 
    public String Message; 

    @SuppressLint("NewApi") 
    public void NachrichtSenden() 
    { 
     async_cient = new AsyncTask<Void, Void, Void>() 
     { 
      @Override 
      protected Void doInBackground(Void... params) 
      { 
       DatagramSocket ds = null; 

       try 
       { 
        ds = new DatagramSocket(); 
        DatagramPacket dp;       
        dp = new DatagramPacket(Message.getBytes(), Message.length(), Main.BroadcastAddress, Main.SERVER_PORT); 
        ds.setBroadcast(true); 
        ds.send(dp); 
       } 
       catch (Exception e) 
       { 
        e.printStackTrace(); 
       } 
       finally 
       { 
        if (ds != null) 
        { 
         ds.close(); 
        } 
       } 
       return null; 
      } 

      protected void onPostExecute(Void result) 
      { 
       super.onPostExecute(result); 
      } 
     }; 

     if (Build.VERSION.SDK_INT >= 11) async_cient.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
     else async_cient.execute(); 
    } 

次に、メインクラスからクラスをインスタンス化する方法を示します。

  //start UDP server 
     Server = new UDP_Server(); 
     Server.runUdpServer(); 

     //UDP Client erstellen 
     Client = new UDP_Client(); 

ここでクライアントとメッセージを送信する方法。

        //Set message 
       Client.Message = "Your message"; 
            //Send message 
       Client.NachrichtSenden(); 

UDP_Serverを停止するには、Server.Server_aktivをfalseに設定します。

上記のメッセージを設定するには、「setMessage(String message)」メソッドなどを記述することもできます。

これがあなたに役立つことを願っています。 最後に私の悪い英語のために申し訳ありません。 :D

+0

Main.BroadcastAddressのようなインスタンスで「シンボルMainを解決できません。およびMain.SERVER_PORT。これを修正する方法はありますか? – ksivakumar

+1

これは、別の.javaファイル(Mainと呼ばれる)で宣言した2つの定数です。あなたはそれらの値をあなたが望む値に置き換えることができます。 – Tim

+0

どのようにMain.MainContext.getApplicationContext()を呼び出しますか?sendBroadcast(i);メインクラスを使わずにファーストクラスで? – ksivakumar

0

ここでは、この記事では、デバイス間または同じモバイル内の2つのアプリケーション間でソケットを確立するための詳細なコードを見つけるでしょう。

以下のコードをテストするには、2つのアプリケーションを作成する必要があります。両方のアプリケーションのマニフェストファイル

、許可

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

第一のAppコードの下に追加します:UDPクライアントソケット

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TableRow 
     android:id="@+id/tr_send_message" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:gravity="center" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" 
     android:layout_alignParentTop="true" 
     android:layout_marginTop="11dp"> 

     <EditText 
      android:id="@+id/edt_send_message" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:layout_marginRight="10dp" 
      android:layout_marginLeft="10dp" 
      android:hint="Enter message" 
      android:inputType="text" /> 

     <Button 
      android:id="@+id/btn_send" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginRight="10dp" 
      android:text="Send" /> 
    </TableRow> 

    <ScrollView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" 
     android:layout_below="@+id/tr_send_message" 
     android:layout_marginTop="25dp" 
     android:id="@+id/scrollView2"> 

     <TextView 
      android:id="@+id/tv_reply_from_server" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:orientation="vertical" /> 
    </ScrollView> 

</RelativeLayout> 

UDPClientSocketActivity.java

import android.os.Bundle; 
import android.os.Handler; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 

import java.io.IOException; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 

/** 
* Created by Girish Bhalerao on 5/4/2017. 
*/ 

public class UDPClientSocketActivity extends AppCompatActivity implements View.OnClickListener { 

    private TextView mTextViewReplyFromServer; 
    private EditText mEditTextSendMessage; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     Button buttonSend = (Button) findViewById(R.id.btn_send); 

     mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message); 
     mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server); 

     buttonSend.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View v) { 

     switch (v.getId()) { 

      case R.id.btn_send: 
       sendMessage(mEditTextSendMessage.getText().toString()); 
       break; 
     } 
    } 

    private void sendMessage(final String message) { 

     final Handler handler = new Handler(); 
     Thread thread = new Thread(new Runnable() { 

      String stringData; 

      @Override 
      public void run() { 

        DatagramSocket ds = null; 
        try { 
         ds = new DatagramSocket(); 
         // IP Address below is the IP address of that Device where server socket is opened. 
         InetAddress serverAddr = InetAddress.getByName("xxx.xxx.xxx.xxx"); 
         DatagramPacket dp; 
         dp = new DatagramPacket(message.getBytes(), message.length(), serverAddr, 9001); 
         ds.send(dp); 

         byte[] lMsg = new byte[1000]; 
         dp = new DatagramPacket(lMsg, lMsg.length); 
         ds.receive(dp); 
         stringData = new String(lMsg, 0, dp.getLength()); 

        } catch (IOException e) { 
         e.printStackTrace(); 
        } finally { 
         if (ds != null) { 
          ds.close(); 
         } 
        } 

       handler.post(new Runnable() { 
        @Override 
        public void run() { 

         String s = mTextViewReplyFromServer.getText().toString(); 
         if (stringData.trim().length() != 0) 
          mTextViewReplyFromServer.setText(s + "\nFrom Server : " + stringData); 

        } 
       }); 
      } 
     }); 

     thread.start(); 
    } 
} 

第二のAppコード - UDPサーバソケット

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <Button 
     android:id="@+id/btn_stop_receiving" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="STOP Receiving data" 
     android:layout_alignParentTop="true" 
     android:enabled="false" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="89dp" /> 

    <ScrollView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_below="@+id/btn_stop_receiving" 
     android:layout_marginTop="35dp" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true"> 

     <TextView 
      android:id="@+id/tv_data_from_client" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:orientation="vertical" /> 
    </ScrollView> 

    <Button 
     android:id="@+id/btn_start_receiving" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="START Receiving data" 
     android:layout_alignParentTop="true" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="14dp" /> 
</RelativeLayout> 

UDPServerSocketActivity.java

import android.os.Bundle; 
import android.os.Handler; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 

import java.io.IOException; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 

/** 
* Created by Girish Bhalerao on 5/4/2017. 
*/ 

public class UDPServerSocketActivity extends AppCompatActivity implements View.OnClickListener { 

    final Handler handler = new Handler(); 

    private Button buttonStartReceiving; 
    private Button buttonStopReceiving; 
    private TextView textViewDataFromClient; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     buttonStartReceiving = (Button) findViewById(R.id.btn_start_receiving); 
     buttonStopReceiving = (Button) findViewById(R.id.btn_stop_receiving); 
     textViewDataFromClient = (TextView) findViewById(R.id.tv_data_from_client); 

     buttonStartReceiving.setOnClickListener(this); 
     buttonStopReceiving.setOnClickListener(this); 

    } 

    private void startServerSocket() { 

     Thread thread = new Thread(new Runnable() { 

      private String stringData = null; 

      @Override 
      public void run() { 

       byte[] msg = new byte[1000]; 
       DatagramPacket dp = new DatagramPacket(msg, msg.length); 
       DatagramSocket ds = null; 
       try { 
        ds = new DatagramSocket(9001); 
        //ds.setSoTimeout(50000); 
        ds.receive(dp); 

        stringData = new String(msg, 0, dp.getLength()); 
        updateUI(stringData); 

        String msgToSender = "Bye Bye "; 
        dp = new DatagramPacket(msgToSender.getBytes(), msgToSender.length(), dp.getAddress(), dp.getPort()); 
        ds.send(dp); 

       } catch (IOException e) { 
        e.printStackTrace(); 
       } finally { 
        if (ds != null) { 
         ds.close(); 
        } 
       } 
      } 

     }); 
     thread.start(); 
    } 

    private void updateUI(final String stringData) { 

     handler.post(new Runnable() { 
      @Override 
      public void run() { 

       String s = textViewDataFromClient.getText().toString(); 
       if (stringData.trim().length() != 0) 
        textViewDataFromClient.setText(s + "\n" + "From Client : " + stringData); 
      } 
     }); 
    } 

    @Override 
    public void onClick(View v) { 

     switch (v.getId()) { 

      case R.id.btn_start_receiving: 

       startServerSocket(); 

       buttonStartReceiving.setEnabled(false); 
       buttonStopReceiving.setEnabled(true); 
       break; 

      case R.id.btn_stop_receiving: 

       //Add logic to stop server socket yourself 

       buttonStartReceiving.setEnabled(true); 
       buttonStopReceiving.setEnabled(false); 
       break; 
     } 
    } 
} 
+0

thats goodしかし、それは1つの文字列を受信し、あなたはサーバーを停止し、それを再起動し、新しい文字列を持つために再度送信する必要があります – Eazyz

関連する問題