2013-10-23 18 views
10

Tôi có thể gửi dữ liệu của mình qua ổ cắm UDP đúng cách, nhưng khi tôi nhận dữ liệu, nó vẫn tiếp tục chờ lệnh nhận được, tôi không biết điều gì đang gây ra lỗi này . tại mã của tôi bên dướiGửi và nhận dữ liệu trên Ổ cắm UDP java android

Tôi có thể thu thập dữ liệu đúng cách ở phía máy chủ từ thiết bị Android, nhưng khi tôi gửi dữ liệu từ phía máy chủ đến thiết bị Android, nó không nhận được. nhưng khi tôi gửi dữ liệu từ máy chủ đến bất kỳ ứng dụng client ví dụ như máy tính khác, nó tiếp nhận và hiển thị dữ liệu 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

Tôi biết đây là một chút cũ bây giờ, nhưng bạn đã bao giờ hình này ra? Bị mắc kẹt trên cùng một vấn đề như bạn. Tôi đang nhận dữ liệu đến máy chủ nhưng khi tôi gửi lại không có gì .. – patrickdamery

+1

hãy thử giảm kích thước dữ liệu cho mỗi lần gửi trong trường hợp UDP, điều này đã giải quyết được vấn đề cho tôi. – user2539602

+0

Tôi đã tìm ra sau một lúc, nhưng kích thước dữ liệu phải giống nhau ở cả đầu gửi và nhận nếu không bạn có thể bị âm thanh bị nhòe – patrickdamery

Trả lời

21

Tài liệu trong Eclipse:

Nhận một gói tin từ ổ cắm này và lưu trữ nó trong gói luận . Tất cả các trường của gói phải được đặt theo dữ liệu nhận được. Nếu dữ liệu nhận được dài hơn kích thước bộ đệm gói thì nó sẽ bị cắt bớt. Phương pháp này chặn cho đến khi nhận được gói hoặc hết thời gian chờ hết hạn.

Lệnh "s.receive(p);" chặn chuỗi cho đến khi nó nhận dữ liệu hoặc đặt hết thời gian bằng setSoTimeout (hết giờ) kết thúc.

Tôi đã thực hiện 2 lớp học để giao tiếp của tôi diễn ra. Đầu tiên UDP-Server:

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

tôi gửi các dữ liệu nhận được để một BroadcastReceiver và ở đó bạn có thể làm những gì mà bạn muốn với dữ liệu.

Và bây giờ khách hàng của tôi gửi dữ liệu. Trong mã này tôi gửi một phát sóng, nhưng tôi nghĩ rằng nó sẽ không có vấn đề để thay đổi mã để gửi đến một IP trực tiếp hoặc một cái gì đó.

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

Và đây là cách bạn khởi tạo lớp học từ lớp chính của mình.

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

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

Và đây là cách gửi thư với khách hàng.

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

Để dừng UDP_Server, chỉ cần đặt Server.Server_aktiv thành false.

Để đặt thông báo ở trên, bạn cũng có thể viết một "setMessage (String message)" methode hoặc một cái gì đó tương tự.

Tôi hy vọng điều này sẽ giúp bạn =). Và cuối cùng xin lỗi vì tiếng anh xấu của tôi. : D

+0

Tôi nhận được lỗi "Không thể giải quyết biểu tượng Chính" tại các trường hợp như Main.BroadcastAddress và Main.SERVER_PORT. Có cách nào để sửa lỗi này? – ksivakumar

+1

Đây là 2 hằng số mà tôi đã khai báo trong tệp .java khác (được gọi là Main). Bạn chỉ có thể thay thế chúng bằng các giá trị bạn muốn chúng có. – Tim

+0

Làm thế nào bạn sẽ gọi Main.MainContext.getApplicationContext(). SendBroadcast (i); trong lớp đầu tiên mà không sử dụng lớp chính? – ksivakumar

0

Ở đây, trong bài đăng này, bạn sẽ tìm thấy mã chi tiết để thiết lập ổ cắm giữa các thiết bị hoặc giữa hai ứng dụng trong cùng một thiết bị di động.

Bạn phải tạo hai ứng dụng để kiểm tra mã bên dưới.

Trong cả hai ứng dụng file manifest, thêm dưới sự cho phép

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

1st đang App: UDP Khách hàng Ổ cắm

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

2 Mã App - UDP server socket

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 tốt nhưng nó chỉ nhận được 1 chuỗi sau đó u cần phải dừng máy chủ và khởi động lại nó và gửi một lần nữa để có chuỗi mới – Eazyz

Các vấn đề liên quan