【问题标题】:Java Multi-thread TCP Socket - Receive message from clients until they become disconnectedJava 多线程 TCP 套接字 - 从客户端接收消息,直到它们断开连接
【发布时间】:2016-06-23 13:53:05
【问题描述】:

我有以下代码来接受来自我的 Java 服务器的多个客户端。

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 中的SocketServerListenToMessage 中。我试图删除 while loop 并且服务器能够接收来自所有客户端的消息,但每个客户端只有一条消息。我希望服务器监听客户端的消息,直到它们断开连接。我该怎么做?

【问题讨论】:

  • 您遇到了“标准 Java 读取问题”is.read(buffer) 读取 达到缓冲区的大小,但不能保证(例如,如果 TCP 数据流使您停滞不前) onl 可能只有 1 个字节)。如果您想阅读完整的byte[],请务必使用 DataInputStream 及其方法readFully(..)
  • @Robert - 对不起,我在 Java 方面不是很好,你能更具体一点,或者至少展示一个代码示例吗?谢谢你,我非常感谢你的帮助。

标签: java c# multithreading sockets tcp


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    相关资源
    最近更新 更多