2016-12-16 74 views
1

我已經檢查過每一個相關的文章,但似乎沒有回答我的問題。無論如何,我正在使用套接字製作一個簡單的聊天服務器客戶端應用程序。在下面的代碼中,會發生什麼,服務器總是可以向客戶端發送數據,但是當客戶端發送到服務器時,除非將數據發送到客戶端,否則它不會出現在服務器的UI中。例如:Android服務器套接字沒有立即收聽

服務器到客戶的情況:

服務器
客戶臨危 「A」
Client顯示 「A」,在客戶端的UI發送 「A」
Server顯示 「A」,在服務器UI

服務器發送 「B」
Server顯示 「B」,在服務器UI
客戶臨危 「B」
只Client顯示 「B」,在客戶端的UI

服務器發送 「C」
Server顯示 「C」 在服務器UI
客戶端在客戶端的UI臨危 「C」
客戶機顯示 「C」

客戶端到服務器的情況:

客戶端發送的客戶端UI 「A」
客戶機顯示 「A」
服務器接收什麼
個 服務器什麼也不顯示在服務器UI

服務器發送 「B」
Server顯示 「B」,在服務器UI
Sever的接收 「A」 從早期
Server顯示// 「A」 在服務器UI
客戶端收到 「B」
Client顯示 「B」,在服務器UI

客戶端發送 「Q」
客戶機顯示 「Q」 在客戶端的UI
客戶端發送 「W」
只 客戶機顯示 「W」 中客戶端的UI
客戶端發送的 「E」
客戶機顯示 「E」 中客戶端的UI
服務器接收無 「Q」, 「W」,或 「E」
服務器發送「的P」
Server顯示 「P」,在服務器UI
服務器顯示 「E」 在服務器UI
客戶端收到 「在客戶端UI

你認爲什麼原因造成這種P」
客戶機顯示 「P」 ?所有我想要的是當客戶端發送數據時,無論多少次,服務器接收,而不必像我目前的情況點擊任何東西。客戶端收到服務器的數據正常。感謝您的任何答案

Client.java

//imports... 

public class RawClient extends Activity { 

int portNo = 8080; 

//globals.. 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_client); 

    editTextAddress = (EditText) findViewById(R.id.address); 
    buttonConnect = (Button) findViewById(R.id.connect); 
    textResponse = (TextView) findViewById(R.id.response); 
    buttonConnect.setOnClickListener(buttonConnectOnClickListener); 

} 


View.OnClickListener buttonConnectOnClickListener = 
     new View.OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       MyClientTask myClientTask = new MyClientTask(
         editTextAddress.getText().toString(), 
         portNo); 
       myClientTask.execute(); 
      } 
     }; 

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

    String dstAddress; 
    int dstPort; 
    String response = ""; 

    MyClientTask(String addr, int port) { 
     dstAddress = addr; 
     dstPort = port; 
    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 

     Socket socket = null; 

     try { 
      socket = new Socket(dstAddress, dstPort); 

      ByteArrayOutputStream byteArrayOutputStream = 
        new ByteArrayOutputStream(1024); 
      byte[] buffer = new byte[1024]; 

      int bytesRead; 
      InputStream inputStream = socket.getInputStream(); 

/* 
* notice: 
* inputStream.read() will block if no data return 
*/ 
      while ((bytesRead = inputStream.read(buffer)) != -1) { 
       byteArrayOutputStream.write(buffer, 0, bytesRead); 
       response += byteArrayOutputStream.toString("UTF-8"); 
      } 

     } catch (UnknownHostException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      response = "UnknownHostException: " + e.toString(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      response = "IOException: " + e.toString(); 
     } finally { 
      if (socket != null) { 
       try { 
        socket.close(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 
     textResponse.setText("Connected"); 
     textResponse.setTextColor(Color.parseColor("#2eb82e")); 
     buttonConnect.setEnabled(false); 

     //reinstantiated thread to recieve messages from server/send message to server 
     sendData = new ClientPassData(
       editTextAddress.getText().toString(), 
       portNo); 
     sendData.execute(); 
    } 

} 

//class called to send data.. 
public class ClientPassData extends AsyncTask<Void, Void, Void> { 
    String dstAddress; 
    int dstPort; 
    String getResponse = ""; 

    ClientPassData(String addr, int port) { 
     dstAddress = addr; 
     dstPort = port; 
    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 

     Socket socket = null; 

     try { 
      socket = new Socket(dstAddress, dstPort); 

      //send data to client  
      PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket 
        .getOutputStream())), true); 
      out.println("" + my_answer); 
      out.flush(); 

      ByteArrayOutputStream byteArrayOutputStream = 
        new ByteArrayOutputStream(1024); 
      byte[] buffer = new byte[1024]; 

      int bytesRead; 
      InputStream inputStream = socket.getInputStream(); 
/* 
* notice: 
* inputStream.read() will block if no data return 
*/ 
      //recieve data from server 
      if (inputStream == null) { 

      } 
      while ((bytesRead = inputStream.read(buffer)) != -1) { 
       byteArrayOutputStream.write(buffer, 0, bytesRead); 
       getResponse += byteArrayOutputStream.toString("UTF-8"); 

      } 

     } catch (UnknownHostException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      getResponse = "UnknownHostException: " + e.toString(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      getResponse = "IOException: " + e.toString(); 
     } finally { 
      if (socket != null) { 
       try { 
        socket.close(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
      super.onPostExecute(result); 
      //do anything with recieved message 
      //reinstantiate itself to continue listening to server 
     sendData = new ClientPassData(
       editTextAddress.getText().toString(), 
       portNo); 
     sendData.execute(); 
     // } 

    } 

} 

public void cl_send(View view) { 
    if(cl_input.getText().toString().length() <= 0){ 
     Toast t = Toast.makeText(getApplicationContext(), "Cannot Send Empty String", Toast.LENGTH_SHORT); 
     t.show(); 
    } else { 
     sendData = new ClientPassData(
       editTextAddress.getText().toString(), 
       portNo); 
     //set data to send to server here 
     //send! 
     sendData.execute(); 
    } 
} 
} 

服務器。java

//imports.. 

public class RawServer extends Activity { 

//globals.. 

TextView info, infoip, serverEnemScore, txtServMyScore; 
String message = ""; 
ServerSocket serverSocket; 

String lastAnswer = ""; 

Socket globalSocket; 
Thread socketServerThread; 

int round = 1; 
int play = 0; //counter to know how many iterations of the game had happened. 
int servMyScore = 0; //variable that holds my score... 
int servEnemyScore = 0; 
String passValue = "", ser_myAnswer = ""; 

SocketServerReplyThread servePass; 

String lineChat = null; //String that will hold message of Client from InputStream 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_server); 

    initiailize(); 

    infoip = (TextView) findViewById(R.id.infoip); 

    infoip.setText(getIpAddress()); 

    socketServerThread = new Thread(new SocketServerThread()); 
    socketServerThread.start(); //starts listening to connecting clients 
} 

private String getIpAddress() { 
    String ip = ""; 
    try { 
     Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface 
       .getNetworkInterfaces(); 
     while (enumNetworkInterfaces.hasMoreElements()) { 
      NetworkInterface networkInterface = enumNetworkInterfaces 
        .nextElement(); 
      Enumeration<InetAddress> enumInetAddress = networkInterface 
        .getInetAddresses(); 
      while (enumInetAddress.hasMoreElements()) { 
       InetAddress inetAddress = enumInetAddress.nextElement(); 

       if (inetAddress.isSiteLocalAddress()) { 
        ip += "SiteLocalAddress: " 
          + inetAddress.getHostAddress() + "\n"; 
       } 
      } 
     } 
    } catch (SocketException e) { 
     e.printStackTrace(); 
     ip += "Something Wrong! " + e.toString() + "\n"; 
    } 

    return ip; 
} //end of getIpAddress 

public void send(View v){ 
    servePass = new SocketServerReplyThread(globalSocket, score); 
    ser_myAnswer = input.getText().toString(); 
    rowMessages.add(new RowMessage(me, ser_myAnswer)); //add to arraylist 
    adapter.notifyDataSetChanged(); //updates the adapter na naay nadungag na data sa arraylist 
    scrollMyListViewToBottom(); 
    input.setText(""); 
    servePass.run(); 
} 

private class SocketServerThread extends Thread { 

    static final int SocketServerPORT = 8080; 
    int count = 0; 
    boolean flag = false; 

    @Override 
    public void run() { 
     try { 
      serverSocket = new ServerSocket(SocketServerPORT); 

      while (true) { 
       Socket socket = serverSocket.accept(); 
       globalSocket = socket; 

       final SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(
         socket, count); 


       BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       lineChat = in.readLine(); 

       RawServer.this.runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         if(!lineChat.equals(lastAnswer) && lineChat.length() > 0){ 
          lastAnswer = lineChat; 
          //display answer from client here 
         } 
        } 
       }); 

      } 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

} 


private class SocketServerReplyThread extends Thread { 

    private Socket hostThreadSocket; 
    int cnt; 

    SocketServerReplyThread(Socket socket, int c) { 
     hostThreadSocket = socket; 
     cnt = c; 
    } 

    @Override 
    public void run() { 
     OutputStream outputStream; 
     String msgReply; 

     try { 
     //send data to client 
      outputStream = hostThreadSocket.getOutputStream(); 
      PrintStream printStream = new PrintStream(outputStream); 
      printStream.print(msgReply); 
      printStream.close(); 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      message += "Something wrong! " + e.toString() + "\n"; 
     } 

    } 

} 

} 

回答

0

即使你的代碼沒問題,你也可以有這樣的問題。例如,服務器可能會過載,網絡可能會受到影響。你必須得到一些保護。

例如,您可以遞增客戶端發送的每條消息。當服務器在消息2之前收到消息3時,它會等待五到六秒鐘。如果在此期間它收到消息,則可以寫入2和3之後。如果沒有收到消息,則可以寫入消息3.如果您從未收到第二條消息,則爲您。

所以,你必須實現你選擇的邏輯系統來防止網絡問題。

相關問題