Java多线程TCP套接字 - 从客户端接收消息,直到它们断开连接

时间:2016-06-23 13:53:06

标签: java c# multithreading sockets tcp

我有以下代码从Java Server接受多个客户端。

private class SocketServerThread extends Thread {
        int count = 0;
        String error_message = null;
        @Override
        public void run() {
            try{
                serverSocket = new ServerSocket(theSocketServerPORT);
                while (true){
                    final Socket socket = serverSocket.accept();
                    count++;
                    runOnUiThread(new Runnable(){
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),"New Client with IP: " + socket.getInetAddress() + " and PORT: " + socket.getPort(),Toast.LENGTH_LONG).show();
                        }
                    });
                    SocketServerListenToMessage socketServerListenToMessage = new SocketServerListenToMessage(socket); 
                    socketServerListenToMessage.run();// Start to Receive now
                }
            }catch (IOException e){
                Log.e("IO ERROR",e.toString());
                error_message = "IO ERROR";
            }catch (Exception e){

                Log.e("EX ERROR",e.toString());
                error_message = "EX ERROR";
            }
            if(error_message!=null){
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),error_message,Toast.LENGTH_LONG).show();
                    }
                });
            }
        }
    }

连接客户端后,我呼叫SocketServerListenToMessage开始收听客户端消息。

以下代码适用于SocketServerListenToMessage

private class SocketServerListenToMessage extends Thread{
        Socket theClientSocket;
        SocketServerListenToMessage(Socket clientSocketListener){
            theClientSocket = clientSocketListener;
            Log.w("SERVER STATUS","Starting to Listen to Clients...");
        }
        @Override
        public void run(){
            try{
                InputStream is = theClientSocket.getInputStream();
                while(true){
                    byte[] lenBytes = new byte[4];
                    is.read(lenBytes, 0, 4);
                    int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16) |
                           ((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff));
                    byte[] receivedBytes = new byte[len];
                    is.read(receivedBytes, 0, len);
                    final String received = new String(receivedBytes, 0, len);

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),"Client Says: " + received, Toast.LENGTH_LONG).show();
                            Log.w("Client Says", received);
                        }
                    });
                }
            }catch (IOException e){
                Log.e("IO ERR FROM LISTEN MSG", e.toString());
            }
            catch (Exception e){
                Log.e("EX ERR FROM LISTEN MSG", e.toString());
            }
        }
    }

使用上面的代码,我可以连接多个客户端。我也可以从我的客户那里收到Message。但问题是我只能从First Client that is become connected to my Server收到一条消息。 secondsoon客户端不是。

以下代码适用于我的ClientSend Message。注意我正在为我的客户使用C#

IPEndPoint serverAddress;
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  //I am using Socket

/*********To Send Message to Server**********/

String toSend = txt_v.Text; //The message came from TextBox.
Task f = Task.Factory.StartNew(() => {
     if (clientSocket.Connected)
     {
       int toSendLen = System.Text.Encoding.ASCII.GetByteCount(toSend);
       byte[] toSendBytes = System.Text.Encoding.ASCII.GetBytes(toSend);
       byte[] toSendLenBytes = System.BitConverter.GetBytes(toSendLen);
       clientSocket.Send(toSendLenBytes);
       clientSocket.Send(toSendBytes);

      }
});

我认为问题出在while loop的{​​{1}}中。我尝试删除SocketServerListenToMessage,并且服务器能够从所有客户端接收消息,但每个客户端只有一条消息。我希望服务器收听客户端的消息,直到它们断开连接。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

我只是让它发挥作用。感谢Link

如果我没记错,从link开始,我使用单线程。所以从我的SocketServerThread我必须改变

SocketServerListenToMessage socketServerListenToMessage = new SocketServerListenToMessage(socket); 
                    socketServerListenToMessage.run();// Start to Receive now

new Thread(new SocketServerListenToMessage(socket)).start();

并将班级SocketServerListenToMessage更改为

private class SocketServerListenToMessage implements Runnable {
        protected Socket clientSocket = null;

        public SocketServerListenToMessage(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }

        @Override
        public void run() {
            try {
                while (true){
                    InputStream is = clientSocket.getInputStream();
                    byte[] lenBytes = new byte[4];
                    is.read(lenBytes, 0, 4);
                    int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16) |
                            ((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff));
                    byte[] receivedBytes = new byte[len];
                    is.read(receivedBytes, 0, len);
                    final String received = new String(receivedBytes, 0, len);

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(), "Client Says: " + received, Toast.LENGTH_LONG).show();
                            Log.w("Client Says", received);

                        }
                    });
                }

            } catch (IOException e) {
                Log.e("IO ERR FROM LISTEN MSG", e.toString());
            } catch (Exception e) {
                Log.e("EX ERR FROM LISTEN MSG", e.toString());
            } finally {
                try{
                    clientSocket.close();
                    Log.w("CLIENT DISCONNECTED", "A client is disconnected.");
                }catch (IOException e){
                    Log.w("IO ERR DISCONNECTION", e.toString());
                }
            }
        }
    }

我只需implement Runnable代替Thread即可Multi