4

我是 android 新手,我正在尝试创建一个服务器套接字。代码如下。

我不断收到警告。可以修吗?我可以忽略它吗?

03-28 15:47:34.460: W/System.err(3185): java.net.BindException: bind failed: EADDRINUSE (Address already in use)

03-28 15:47:34.460: W/System.err(3185):     at libcore.io.IoBridge.bind(IoBridge.java:89)

03-28 15:47:34.460: W/System.err(3185):     at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:150)

03-28 15:47:34.460: W/System.err(3185):     at java.net.ServerSocket.<init>(ServerSocket.java:100)

03-28 15:47:34.470: W/System.err(3185):     at java.net.ServerSocket.<init>(ServerSocket.java:69)

03-28 15:47:34.470: W/System.err(3185):     at <path>$server.run(<filename>.java:302)

03-28 15:47:34.470: W/System.err(3185):     at java.lang.Thread.run(Thread.java:856)
03-28 15:47:34.470: W/System.err(3185): Caused by: libcore.io.ErrnoException: bind failed: EADDRINUSE (Address already in use)

03-28 15:47:34.470: W/System.err(3185):     at libcore.io.Posix.bind(Native Method)
03-28 15:47:34.470: W/System.err(3185):     at ibcore.io.ForwardingOs.bind(ForwardingOs.java:39)
03-28 15:47:34.470: W/System.err(3185):     at libcore.io.IoBridge.bind(IoBridge.java:87)
03-28 15:47:34.470: W/System.err(3185):     ... 5 more

03-28 15:47:34.470: W/System.err(3185): java.lang.NullPointerException
03-28 15:47:34.490: W/System.err(3185):     at <path>Provider$server.run(<filename>.java:315)

03-28 15:47:34.490: W/System.err(3185):     at java.lang.Thread.run(Thread.java:856)

代码:

class server implements Runnable {

        public void run() {


        ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(10000);
            } catch (IOException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }
            //  Log.d("Recieving ", "Server Socket Created");


            try {
                while(true) {
                    // Blocks until a connection occurs:
                    try {

                Socket client = serverSocket.accept();
                        //Log.d("Recieving ", "Client request accepted");
                        str_proc tk = new str_proc(client);
                        tk.start();

                    } catch (IOException e1) {

                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                        Log.d("Recieving ", "Problem creating socket for listening");

                    }
                }//while true loop ends

            }catch (Exception e){
                e.printStackTrace();
            }
        }
}
4

2 回答 2

3

您的异常处理非常出色。

创建之后的 catchServerSocket根本不应该存在:它应该在使用 的代码之后ServerSocket,在这种情况下,它可以与现有的第二个 catch 结合使用。依赖于前一个try块中代码成功的代码应该在该try块内。

但是,连续出现该错误的唯一方法是连续启动线程,这无论如何都没有意义,因为在任何给定的 TCP 端口上只能有一个侦听器。

所以调查你为什么一遍又一遍地启动线程,然后停止它,

于 2013-03-28T23:47:42.403 回答
0

你可以从另一个线程调用close() ,accept() 调用会抛出一个 SocketException。这样,在下一次调用 ServerSocket 构造函数时,您将不会得到“ java.net.BindException : bind failed: EADDRINUSE”。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"`enter code here`
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="project.vasile.emanuel.gresanu.test_server_socket.MainActivity">

<Button
    android:id="@+id/btn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Click"/>
</RelativeLayout>

主要活动

public class MainActivity extends AppCompatActivity {

    private static final String TAG=MainActivity.class.getSimpleName();
    private static boolean isClick;
    private My_Server My_Server;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn=(Button) findViewById(R.id.btn);
        isClick=false;
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                 if(!isClick)
                 {
                     Log.i(TAG,"Initilize and Running My_Server");
                     My_Server =new My_Server();
                     if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.HONEYCOMB)
                     {
                         My_Server.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,(Void[])null);
                     }
                     else
                     {
                         My_Server.execute((Void[])null);
                     }
                     isClick=true;
                 }
                else
                 {
                    if(null!= My_Server)
                    {
                        My_Server.cancelAccept();
                        isClick=false;
                    }
                 }
            }
        });
    }
}

我的服务器

public class My_Server extends AsyncTask<Void, Void, Void> {

    private static final String TAG = My_Server.class.getSimpleName();
    private static final int PORT = 8091;
    private static boolean isExiting;
    private ServerSocket serverSocket;

    @Override
    protected Void doInBackground(Void... params) {
        isExiting = false;
        try {
            serverSocket = new ServerSocket(PORT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Socket clientSocket=null;
        if(null!=serverSocket)
        while (!isExiting) {
            try {
                Log.i(TAG, "Waiting for a new connection");
                clientSocket=serverSocket.accept();
                Log.i(TAG, "Connction accepted");
                //Do something with the new client
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, e.getMessage());
                if(null!=this.serverSocket&& !serverSocket.isClosed()) {
                    try {
                        Log.i(TAG,"Closing Server connection");
                        this.serverSocket.close();
                    } catch (IOException e2) {
                        e2.printStackTrace();
                    }
                }
            }
        }
        try {
            Log.i(TAG,"Closing the connection");
            if(null!=serverSocket && !serverSocket.isClosed()) {
                serverSocket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,e.getMessage());
        }
        return null;
    }

    public void cancelAccept() {
        Log.i(TAG, "cancelAccept()");
        isExiting = true;
        if(null!=this.serverSocket&& !serverSocket.isClosed())
        {
            try {
                Log.i(TAG,"Closing Server connection in onCancelled");
                this.serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.gc();
    }
}
于 2016-01-25T17:29:23.953 回答