我是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();
}
}
}
答案 0 :(得分:3)
你的异常处理已经到了极点。
创建ServerSocket
之后的捕获不应该存在:它应该在使用ServerSocket
的代码之后,在这种情况下它可以与现有的第二个catch一起使用。依赖于先前try
块中代码成功的代码应位于try
块内。
然而,你可以连续获得该错误的唯一方法是你是否连续启动线程,这无论如何都没有意义,因为你在任何给定的TCP端口只能有一个监听器。
因此,请调查为什么一遍又一遍地启动线程,然后停止它,
答案 1 :(得分:0)
您可以从另一个线程调用close(),而accept()调用将抛出SocketException。通过这种方式,在下一次调用ServerSocket构造函数时,您将无法获得&#34; java.net.BindException:绑定失败:EADDRINUSE&#34;。
<强> 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>
<强> MainActivity 强>
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;
}
}
}
});
}
}
<强> MY_SERVER 强>
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();
}
}