【问题标题】:Why I can't receive data by a socket为什么我不能通过套接字接收数据
【发布时间】:2019-07-26 13:51:14
【问题描述】:

我可以在python中发送数据并在服务器中接收,但是在睡眠超过1ms之后(如果做一些For-loops(例如: for i in range(0, 60): print i),结果是一样的),我用socket发送数据,但是java服务器收不到。

有代码: 一个客户端是用python2写的:

address = ('127.0.0.1', 9898)
ccc = socket(AF_INET, SOCK_STREAM)
ccc.connect(address)
ccc.send("client" + str(1) + ":before time.sleep send1111\n")
time.sleep(0.001)
ccc.send("client2:222222 after time.sleep\n")# if sleep 0.0009,can received,but 0.001 can't

服务器是用java编写的:

 ReceiveListener listener = new ReceiveListener() {
            @Override
            public void onReceived(int clientId, String msg) {
                System.out.println(clientId + ":" + msg);
            }
        };
        ClientManager clientManager = ClientManager.getInstance(listener, 9898);
        clientManager.start();

这是管理客户端的类:

public class ClientManager {
    private static ServerThread serverThread = null;
    private static ClientManager instance = null;
    private final int port;
    private ReceiveListener receiveListener = null;

    private ClientManager(ReceiveListener receiveListener, int port) {
        this.receiveListener = receiveListener;
        this.port = port;
        serverThread = new ServerThread(receiveListener, port);
    }

    public static ClientManager getInstance(ReceiveListener receiveListener, int port) {
        if (instance == null) {
            synchronized (ClientManager.class) {
                if (instance == null) {
                    instance = new ClientManager(receiveListener, port);
                }
            }
        }
        return instance;
    }

    public void stop() {
        serverThread.Stop();
        serverThread = null;
    }

    public void start() {
        if (serverThread == null) {
            serverThread = new ServerThread(receiveListener, port);
        }
        new Thread(serverThread).start();
    }

    public static class ServerThread implements Runnable {
        private ReceiveListener receiveListener;
        private static Map<Integer, HandleMsgTask> tasks = new HashMap<>();
        private final AtomicBoolean isExit = new AtomicBoolean(false);
        private ServerSocket server;
        int i = 0;

        public ServerThread(ReceiveListener receiveListener, int port) {
            try {
                this.receiveListener = receiveListener;
                this.server = new ServerSocket(port);
            } catch (IOException e) {
                System.out.println("failed:" + e.getMessage());
            }
        }

        @Override
        public void run() {
            try {
                while (!isExit.get()) {
                    System.out.println("wait devices... ... " + i);
                    Socket client = server.accept();
                    HandleMsgTask task = new HandleMsgTask(i, client, receiveListener);
                    new Thread(task).start();
                    tasks.put(i, task);
                    i++;
                    System.out.println("No:" + i);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public static class HandleMsgTask implements Runnable {
            public final int clientId;
            public final Socket client;
            public static boolean connectStop = false;
            private final ReceiveListener ReceiveListener;

            public HandleMsgTask(int i, Socket client, ReceiveListener ReceiveListener) {
                this.clientId = i;
                this.client = client;
                this.ReceiveListener = ReceiveListener;
            }

            public void disconnectClient() {
                connectStop = true;
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void run() {
                try {
                    final String address = client.getRemoteSocketAddress().toString();
                    System.out.println(clientId + ":" + address);
                    InputStream inputStream = client.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                    while (reader.ready() && !connectStop) {
                        String line = reader.readLine();
                        if (ReceiveListener != null) {
                            ReceiveListener.onReceived(clientId, line);
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        public void Stop() {
            if (tasks != null) {
                for (HandleMsgTask task : tasks.values()) {
                    task.disconnectClient();
                }
                tasks.clear();
            }
            isExit.set(true);
            if (server != null) {
                try {
                    server.close();
                    System.out.println("close server");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

有人可以帮我吗?谢谢!

【问题讨论】:

  • 因为你误用了ready()。在此读取循环中您没有其他任何事情可做,因此即使对其进行测试也毫无意义,并且当它为假时您实际上正在退出循环,这意味着除非在您进入它的那一刻数据已经可以读取你会想念它的。只需删除这个毫无意义的测试并让您的循环阻塞readLine()。如果你得到null,则退出循环:否则你将忽略流的结束并毫无意义地继续读取循环。并且不要在网络代码中添加睡眠。
  • 非常感谢。问题解决了!

标签: java python sockets


【解决方案1】:

正如 user207421 所说,我误用了 ready();我更改下面的代码并解决问题: 编辑:

 while (!bIsStopped.get() && ((line = reader.readLine()) != null)) {
                    if (newMsgRecListener != null) {
                        newMsgRecListener.onMsgRec(clientId, line);
                    }
                }

【讨论】:

  • 你应该先测试bIsStopped,而不是在你可能已经屏蔽并阅读了一行之后。
猜你喜欢
  • 1970-01-01
  • 2016-05-29
  • 1970-01-01
  • 2012-02-12
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多