2013-10-23 23 views
10

Verilerimi UDP soketi üzerinden düzgün bir şekilde gönderebiliyorum, ancak veri aldığımda almayı beklerken beklemeye alıyorum ne olduğunu bilmiyorum Lütfen bir göz atınUDP Soketi hakkında veri gönderip al ver java android

Aşağıdaki kodumda, Android cihazından sunucu tarafındaki verileri doğru bir şekilde alabilirim, ancak sunucu tarafında veri aldığımda Android cihazına almaz. i başka bir istemci örneğin bilgisayar uygulamasına sunucudan veri gönderdiğinizde ancak alıp rpoperly verileri gösterir Eclipse

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

ben bu şimdi biraz eski olduğunu biliyorum, ama hiç bu bir fark ettin? Seninle aynı sorun üzerinde sıkışmış. Sunucuya veri alıyorum ama hiçbir şey göndermediğimde .. – patrickdamery

+1

UDP durumunda her gönderim için veri boyutunu azaltmayı deneyin, bu benim için sorunu çözdü. – user2539602

+0

Bir süre sonra çözdüm ama veri boyutu aynı anda hem gönderen hem de alıcıda aynı olmalıdır, aksi halde sizde kesintili ses alabilirsiniz – patrickdamery

cevap

21

Dokümantasyon:

argüman paketinde bu soket ve bu bilgiyi saklar bir paket alır . Tüm paket alanları, alınan verilere göre ayarlanmalıdır. alınan veri paket tampon boyutundan daha uzunsa, kesilir. Bu yöntem, bir paket alınana veya bir zamanaşımının kullanım süresinin dolmasına kadar engellenir.

" s.receive(p);" komutu blokları veri veya setSoTimeout (zaman aşımı) ile belirlenen zaman aşımı receices kadar iplik bitti.

İletişimimi sağlamak için 2 sınıf hazırladım. İlk UDP-Sunucu:

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; 
    } 
} 

Bir BroadcastReceiver alınan veri göndermek ve orada size verilerle için ne kadar istediğiniz yapabilirsiniz.

Ve şimdi müşterim verileri gönderiyor. Bu kodda bir yayın gönderiyorum, ancak doğrudan bir IP'ye veya başka bir şeye yollamak için kodu değiştirmenin bir problem olmayacağını düşünüyorum. Eğer ana sınıfından sınıfları örneğini burada nasıl

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(); 
    } 

Ve olduğunu.

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

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

Ve burada istemci ile bir mesaj nasıl gönderilir.

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

UDP_Server'ı durdurmak için Server.Server_aktiv öğesini false olarak ayarlayın.

Yukarıdaki mesajı ayarlamak için bir "setMessage (String message)" metodu veya bunun gibi bir şey de yazabilirsiniz.

Umarım bu size yardımcı olacaktır =). Ve son olarak benim kötü ingilizce için özür dilerim. : D

+0

Bir hata alıyorum, "Ana Sembolü çözemiyorum" gibi durumlarda Main.BroadcastAddress ve Main.SERVER_PORT. Bunu düzeltmenin bir yolu var mı? – ksivakumar

+1

Bunlar, başka bir .java dosyasında (Ana olarak adlandırılır) bildirdiğim 2 sabittir. Onları sahip olmasını istediğiniz değerlerle değiştirebilirsiniz. – Tim

+0

Main.MainContext.getApplicationContext() yöntemini nasıl çağırırsınız? SendBroadcast (i); Ana sınıfı kullanmadan birinci sınıfta? – ksivakumar

0

Bu yazıda, cihazlar arasında ya da aynı uygulamada iki uygulama arasında soket oluşturmak için ayrıntılı kod bulacaksınız.

Aşağıdaki kodu sınamak için iki uygulama oluşturmanız gerekir.UDP İstemci Soket

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> 
: Her iki uygulamanın Bildiri dosyasının yılında

, izni

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

1 Uygulama kodu aşağıda eklemek

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(); 
    } 
} 

2 App Kodu - UDP Sunucu Soket

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

iyi ama sadece 1 string alıyor, sonra sunucuyu durdurup yeniden başlatmalı ve yeni dizgeye sahip olmak için tekrar gönder – Eazyz