【问题标题】:Android Server Socket not listening immediatelyAndroid服务器套接字没有立即监听
【发布时间】:2017-05-01 21:29:01
【问题描述】:

我已经检查了所有与此相关的帖子,但似乎没有一个回答我的问题。无论如何,我正在使用套接字制作一个简单的聊天服务器客户端应用程序。在下面的代码中,发生的情况是,服务器始终可以向客户端发送数据,但是当客户端向服务器发送数据时,除非您向客户端发送数据,否则它不会出现在服务器的 UI 中。例如:

服务器到客户端的情况:

服务器发送“A”
服务器在服务器 UI 中显示“A”
客户收到“A”
客户端在客户端 UI 中显示“A”

服务器发送“B”
服务器在服务器 UI 中显示“B”
客户收到“B”
客户端在客户端 UI 中显示“B”

服务器发送“C”
服务器在服务器 UI 中显示“C”
客户收到“C”
客户端在客户端 UI 中显示“C”

客户端到服务器的情况:

客户端发送“A”
客户端在客户端 UI 中显示“A”
服务器什么也没收到
服务器在服务器 UI 中不显示任何内容

服务器发送“B”
服务器在服务器 UI 中显示“B”
服务器收到“A”//来自较早
服务器在服务器 UI 中显示“A”
客户收到“B”
客户端在服务器 UI 中显示“B”

客户端发送“Q”
客户端在客户端 UI 中显示“Q”
客户端发送“W”
客户端在客户端 UI 中显示“W”
客户端发送“E”
客户端在客户端 UI 中显示“E”
服务器没有收到“Q”、“W”或“E”
服务器发送“P”
服务器在服务器 UI 中显示“P”
服务器在服务器 UI 中显示“E”
客户收到“P”
客户端在客户端 UI 中显示“P”

您认为这是什么原因造成的?我想要的只是当客户端发送数据无论多少次,服务器接收而无需像我目前的情况那样点击任何东西。客户端接收服务器的数据很好。感谢您的任何回答

客户端.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";
        }

    }

}

}

【问题讨论】:

    标签: android sockets networking server client


    【解决方案1】:

    即使你的代码没问题,你也可能遇到这种问题。例如,服务器可能过载,网络可能饱和。你必须有一些保护。

    例如,您可以递增客户端发送的每条消息。当服务器在消息 2 之前收到消息 3 时,它会等待五六秒。如果在此期间收到消息,你可以写 2 和 3 之后。如果你没有收到,你可以写消息 3。如果你没有收到第二条消息,你。

    因此,您必须实施您选择的逻辑系统来防止网络问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-06
      • 1970-01-01
      • 2013-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多