18848


今現在、AndroidでUDPによるネット通信を伴うプログラムを勉強していますが、どうもエラーが取り除けないので質問させていただきます。

作成中のプログラムは、UDP通信を用いてテキストデータを相手方に投げようとしています。何度も試行錯誤しましたがBindExceptionとErrnoExceptionだけが取り除けないのでコードの変え方や取り除き方を教えてただければと思います。以下がコード(一部抜粋)になります。  
よろしくお願いします。

MainActivity.java

[code]

    public class MainActivity extends AppCompatActivity {
    
        static Button btnSend,;
        static EditText txtIPAddress,txtPort,txtMessage;
        static String address,message;
        static int port;
        Context context;
        AsyncTaskTest1 task1;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //全てのボタンやテキストなどのIDを見付ける。
            txtIPAddress =(EditText)findViewById(R.id.txtIPAddress);
            txtPort =(EditText)findViewById(R.id.txtPort);
            txtMessage = (EditText)findViewById(R.id.txtMessage);
    
            btnMessage = (Button)findViewById(R.id.btnMessage);
    
            txtMessageBox = (TextView)findViewById(R.id.txtMessageBox);
    
            btnMessage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    //まずは入力された値を確定し、接続を確立する
                    address = txtIPAddress.getText().toString();
                    port = Integer.parseInt(txtPort.getText().toString());
                    message = txtMessage.getText().toString();
    
                    if(message.equals("")){
                        txtMessageBox.setText("メッセージを入力してください。");
                    }else{
                        txtMessageBox.setText(message);
                    }
    
                    try {
                        task1 = new AsyncTaskTest1(context);
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    task1.execute();
    
                }
            });
        }
    ~~以下略~~
    
[/code]

AsyncTaskTest1.java

[code]

    public class AsyncTaskTest1 extends AsyncTask<Void,Void,Void> {
    
    ~~中略~~
    
        public AsyncTaskTest1(Context context) throws UnknownHostException {
            try {
                this.context = context;
                this.address = MainActivity.address;
                this.message = MainActivity.message;
                this.txtMessageBox = MainActivity.txtMessageBox;
                this.port = MainActivity.port;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        protected Void doInBackground(Void... params) {
            try {
                this.addar = InetAddress.getByName(address);
                this.buf = message.getBytes();
                this.dSocket = new DatagramSocket();
                this.packet1 = new DatagramPacket(buf, buf.length,addar,port);
                dSocket.send(packet1);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    
[/code]

このコードになる前に、出ていたエラーの対処としてSocketの引数に指定していた相手のアドレス、ポート番号をPacketの引数に持っていきました。これで正しいのでしょうか？あるいは両方の引数に指定すべきなのでしょうか？  
また、btnMessageを押した際に、上記のエラーが出てきますが、うまくバインドできていないことが原因かと思われます。正しいバインドの方法などが今一つ明確ではないです。疑問は尽きませんが、お力添えの方よろしくお願いします。


CC BY-SA 3.0
2015-11-11T02:09:13.110
18649
2015-11-15T11:48:17.003
2015-11-12T10:39:24.167
5778
12789
question
android java socket
AndroidのBindExceptionとErrnoExceptionについて


(ソケットをcloseしていない、などプログラムとして不適切な点はここでは置いておいて、)`doInBackground`メソッドに書かれている処理でエラー無く送信できるはずです。

`AndroidManifest.xml`でパーミッションを与えておかないと`ErrnoException`(をラップした`SocketException`)例外が発生しますが、行えているでしょうか。

[code]

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

`BindException`
については、`DatagramSocket`コンストラクタにポート番号を指定している場合に、ボタンを2回(以上)押すと発生していたのではないでしょうか。  
上記のコードでは再現方法が分かりませんでした。

>
> Socketの引数に指定していた相手のアドレス、ポート番号をPacketの引数に持っていきました。これで正しいのでしょうか？あるいは両方の引数に指定すべきなのでしょうか？

`DatagramSocket`コンストラクタに指定するアドレス/ポート番号と、`DatagramPacket`コンストラクタに指定するアドレス/ポート番号は意味が異なります。  
簡単に言うと、`DatagramSocket`コンストラクタで指定するのは受信する場合の情報(なので今回は不要)、`DatagramPacket`の方は送信先の情報です。  
[Android](http://developer.android.com/reference/java/net/DatagramSocket.html#DatagramSocket\(int,%20java.net.InetAddress\))(あるいは[JDK](https://docs.oracle.com/javase/jp/8/api/java/net/DatagramSocket.html#DatagramSocket-
int-java.net.InetAddress-))のリファレンスで引数の意味やデフォルトコンストラクタの挙動も参照してみてください。

上記から解決の糸口がつかめないようでしたら、スタックトレースを載せるなど、もう少し発生するエラーについて詳しく正確に書いてみてください。


CC BY-SA 3.0
2015-11-15T11:39:33.350
18848
2015-11-15T11:48:17.003
2015-11-15T11:48:17.003
2808
2808
18649
answer