2017-04-22 18 views
-1

以下是“TCP SERVER”代码,当任何客户端第一次连接时代码运行的很好,但是一旦客户端断开连接并再次连接到TCP SERVER,则客户端连接成功但不能发送数据。如何解决Tcp服务器中的bug

如何检测客户端与服务器断开连接?

import android.content.Context; 
import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.net.wifi.WifiManager; 
import android.os.AsyncTask; 
import android.os.CountDownTimer; 
import android.os.Handler; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.util.Log; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 
import android.widget.Toast; 
import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.Inet4Address; 
import java.net.Inet6Address; 
import java.net.InetAddress; 
import java.net.NetworkInterface; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.Enumeration; 

public class MainActivity extends AppCompatActivity { 

    TextView tvStatus; 
    EditText etPort, etMsg, etTransmit; 
    Button btnListen, btnServerSend; 
    Handler UIHandler; 

    private int SERVERPORT1; 
    private InetAddress addr; 
    private ServerSocket serverSocket; 
    private Socket clientSocket = null; 
    private BufferedReader in; 
    private PrintWriter out; 

    // public static final int SERVERPORT = 3000; 
    private WifiManager wifiManager = null; 
    private WifiManager.WifiLock lock = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     wifi(); 
     UIHandler = new Handler(); 
     tvStatus = (TextView) findViewById(R.id.tvStatus); 

     etMsg = (EditText) findViewById(R.id.etMsg); 
     etTransmit = (EditText) findViewById(R.id.etTransmit); 
     etPort = (EditText) findViewById(R.id.etPort); 

     btnListen = (Button) findViewById(R.id.btnListen); 
     btnServerSend = (Button) findViewById(R.id.btnServerSend); 
// ******************* Register controls end ****************************** 

     btnListen.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       new ServerClass().execute(etPort.getText().toString()); 
      } 
     }); 
    } 

    public String getLocalIpAddress() throws Exception { 
     String resultIpv6 = ""; 
     String resultIpv4 = ""; 

     for (Enumeration en = NetworkInterface.getNetworkInterfaces(); 
       en.hasMoreElements();) { 

      NetworkInterface intf = (NetworkInterface) en.nextElement(); 
      for (Enumeration enumIpAddr = intf.getInetAddresses(); 
        enumIpAddr.hasMoreElements();) { 

       InetAddress inetAddress = (InetAddress) enumIpAddr.nextElement(); 
       if (!inetAddress.isLoopbackAddress()) { 
        if (inetAddress instanceof Inet4Address) { 
         resultIpv4 = inetAddress.getHostAddress().toString(); 
        } else if (inetAddress instanceof Inet6Address) { 
         resultIpv6 = inetAddress.getHostAddress().toString(); 
        } 
       } 
      } 
     } 
     return ((resultIpv4.length() > 0) ? resultIpv4 : resultIpv6); 
    } 

    private class ServerClass extends AsyncTask<String, Object, String> { 
     private String input; 

     @Override 
     protected String doInBackground(String... params) { 
     try { 
      SERVERPORT1 = Integer.parseInt(params[0]); 
      addr = InetAddress.getByName(getLocalIpAddress()); 
      serverSocket = new ServerSocket(SERVERPORT1, 0, addr); 

      while (true) { 
       clientSocket = serverSocket.accept(); 
       clientSocket.setTcpNoDelay(true); 
       MainActivity.this.runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
        tvStatus.setText(clientSocket.getInetAddress().toString() + " Client connected"); 
         Toast.makeText(MainActivity.this, "Server started...", Toast.LENGTH_SHORT).show(); 
        } 
       }); 
       in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
       out = new PrintWriter(clientSocket.getOutputStream(), true); 
       if (!Thread.currentThread().isInterrupted()) { 
        input = in.readLine(); 
        if (input != null) { 
         UIHandler.post(new updateUIThread1(input.toString())); 
         out.println("Received from client: " + input); 
        } else { 
         MainActivity.this.runOnUiThread(new Runnable() { 
          @Override 
          public void run() { 
           new ServerClass().execute(etPort.getText().toString()); 
          } 
         }); 
        } 
       } 
      } 


     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
    } 

    private class updateUIThread1 implements Runnable { 
     private String input = null; 

     public updateUIThread1(String input) { 
      this.input = input; 
     } 

     @Override 
     public void run() { 
      if (input.getBytes().length != 0) { 
       etMsg.append("\n" + input.toString()); 
       Toast.makeText(MainActivity.this, "Answer: " + input, Toast.LENGTH_SHORT).show(); 
      }else { 
       Toast.makeText(MainActivity.this, "Empty", Toast.LENGTH_SHORT).show(); 
      } 
     } 
    } 
} 

日志显示,如:

04-22 12:57:05.799 10857-10931/com.chat.admin.clientserver I/System.out: [CDS]shutdownInput in read 
04-22 12:57:05.799 10857-10931/com.chat.admin.clientserver I/System.out: [CDS]shutdownInput in read 
04-22 12:57:05.799 10857-10931/com.chat.admin.clientserver I/System.out: [CDS]shutdownInput in read 
04-22 12:57:05.799 10857-10931/com.chat.admin.clientserver I/System.out: [CDS]shutdownInput in read 
04-22 12:57:05.799 10857-10931/com.chat.admin.clientserver I/System.out: [CDS]shutdownInput in read 

                    read: unexpected EOF! 
+0

不要对没有引用的文本使用引号格式。 – EJP

回答

1

不要创建如果客户端断开连接一个新的服务器。

相反,你应该有一个循环,所以你可以再次调用.accept()等待一个新的客户端。

+0

我是新手,所以你可以请详细解释或在你的答案中提及。 –

+1

我不会。请尝试添加从accept()语句开始的while(true)循环。编辑您的帖子,以便我们可以看到您的操作。 – greenapps

+0

部分解决,但在每个连接的服务器上只收到一条消息。延迟增加。请检查我的更新代码。提前致谢。 –