2

我正在创建一个执行以下任务的服务器应用程序

  • 接受来自客户端的连接
  • 将每个客户端连接处理到单独的线程
  • 从客户端接收数据
  • 向客户端发送数据

我能够连接客户端但无法从客户端接收数据

仅当客户端断开连接时,我的控制台中才能看到数据..!!!

代码 :-

public class ServerListener {

    public static void main(String[] args) {
        new ServerListener().startServer();
    }

    public void startServer() {
        final ExecutorService clientProcessingPool = Executors
                .newFixedThreadPool(10);

        Runnable serverTask = new Runnable() {
            @Override
            public void run() {
                try {
                    ServerSocket serverSocket = new ServerSocket(8000);
                    System.out.println("Waiting for clients to connect...");
                    while (true) {
                        Socket clientSocket = serverSocket.accept();
                        clientProcessingPool
                                .submit(new ClientTask(clientSocket));
                    }
                } catch (IOException e) {
                    System.err.println("Unable to process client request");
                    e.printStackTrace();
                }
            }
        };
        Thread serverThread = new Thread(serverTask);
        serverThread.start();
    }

    private class ClientTask implements Runnable {
        private final Socket clientSocket;

        private ClientTask(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }

        @Override
        public void run() {
            System.out.println("Got a client !");
            try {
            /* Get Data From Client */
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(clientSocket.getInputStream()));
                String clientData = "";
                clientData = reader.readLine();
                System.out.println("Data From Client :" + clientData);

            /* Send Data To Client */

                //Code

                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
4

3 回答 3

7

您的实施有问题

BufferedReader#readLine

读取一行文本。一行被认为是由换行符 ('\n')、回车符 ('\r') 或紧跟换行符的回车符中的任何一个终止的。

换句话说,如果您的客户端从未发送\n\r字符,则该方法将不会结束,直到IOException由于断开连接而被抛出。

解决方案

替换此代码:

BufferedReader reader = new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));
String clientData = "";
clientData = reader.readLine();

和:

int red = -1;
byte[] buffer = new byte[5*1024]; // a read buffer of 5KiB
byte[] redData;
StringBuilder clientData = new StringBuilder();
String redDataText;
while ((red = clientSocket.getInputStream().read(buffer)) > -1) {
    redData = new byte[red];
    System.arraycopy(buffer, 0, redData, 0, red);
    redDataText = new String(redData,"UTF-8"); // assumption that client sends data UTF-8 encoded
    System.out.println("message part recieved:" + redDataText); 
    clientData.append(redDataText);
}
System.out.println("Data From Client :" + clientData.toString());

InputStream#read

从输入流中读取一些字节并将它们存储到缓冲区数组 b. 实际读取的字节数以整数形式返回。在输入数据可用、检测到文件结尾或引发异常之前,此方法会一直阻塞。

将在其执行的确切时刻读取尽可能多的字节 - 它基本上是缓冲读取。由于这些是原始字节,因此在将它们转换为 String时,您必须知道其编码才能正确显示它们(即“UTF-8”部分)。如果您的客户端发送字节的编码是其他编码,您可能需要更改它以便在控制台输出中获得正确的文本。

我推荐阅读官方教程课程:

于 2013-08-24T12:44:59.690 回答
1

BufferedReader.readLine() 只会在有行尾或流尾时返回。确保客户端发送换行符,或使用不同的方式来读取输入流,例如:

int ch = 0;
while ((ch = instream.read()) >= 0) {
    // do sometyhing with the character off the input stream.
    System.out.println("Got byte " + ch);
}
// will get here when the input stream is closed.
于 2013-08-24T12:44:42.347 回答
0

可能是您的 ExecutorService (不是?)被调用的问题。

尝试替代

clientProcessingPool.submit(new ClientTask(clientSocket));

BufferedReader reader = new BufferedReader(
    new InputStreamReader(clientSocket.getInputStream()));
String line;
while( (line = reader.readLine()) != null) // just read everything
   System.out.println(line);

看看你是否得到任何输出。

于 2013-08-24T12:13:30.053 回答