写入套接字的速度比对方读取的速度快时如何避免java服务器挂起

我正在使用 TCP java 服务器从客户端接收数据并将数据发送回客户端。问题是,当服务器写入客户端套接字的速度快于客户端读取的速度时,服务器会挂起/冻结,并且不再处理来自其他客户端的任何数据。


例如,服务器向客户端套接字写入 3 kb/s,而客户端只能读取 1 kb/s。我如何识别这个,所以我可以关闭这个套接字并停止写入它?


怎么了?数据是否被缓冲?


我使用以下代码写入数据:


this.out_ = new PrintWriter(this.clientSocket_.getOutputStream(), true);


this.out_.print(msg);

编辑:完整代码


Main.java


import java.net.Socket;

import java.net.SocketAddress;

import java.net.InetSocketAddress;

import java.io.IOException;

import java.util.HashMap;

import java.net.ServerSocket;

import java.net.SocketTimeoutException;


public class Main

{

    static ServerSocket serverSocket_;

    static HashMap<String, ServerInformation> servers_;

    static int verboseLevel_;

    static int threadTimeout_;

    static int masterPort_;

    static int serverNumber_;

    static int socketTimeOut_;


    static {

        Main.serverSocket_ = null;

        Main.servers_ = new HashMap<String, ServerInformation>();

        Main.verboseLevel_ = 5;

        Main.threadTimeout_ = 10;

        Main.masterPort_ = 6510;

        Main.serverNumber_ = 1;

        Main.socketTimeOut_ = 6000;

    }


    public static void main(final String[] args) {

        try {

            setupServerAndCleanup(Main.masterPort_);

            while (true) {

                handleIncomingConnection();

            }

        }

        catch (IOException e) {

            e.printStackTrace();

        }

    }


    static void setupServerAndCleanup(final int port) throws IOException {

        (Main.serverSocket_ = new ServerSocket()).setReuseAddress(true);

        Main.serverSocket_.bind(new InetSocketAddress(Main.masterPort_));

        System.out.println("Server socket up and running on port " + Main.masterPort_);

        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

            @Override

            public void run() {

                if (Main.serverSocket_ != null) {

                    try {

                        Main.serverSocket_.close();

                        System.out.println("Server socket closed, port released");

                    }



茅侃侃
浏览 94回答 1
1回答

梵蒂冈之花

怎么了?数据是否被缓冲?TCP 写缓冲区将溢出。发生的情况取决于您使用的 Channel 类型。如果通道在阻塞模式下阻塞,线程写入数据将阻塞等待客户端接收数据。如果通道处于非阻塞模式,y̶o̶u̶̶a̶r̶e̶̶m̶o̶s̶t̶̶l̶i̶k̶e̶l̶y̶̶t̶o̶̶r̶e̶c̶e̶i̶v̶e̶̶I̶O̶E̶x̶c̶e̶p̶t̶i̶o̶n̶ 写入返回零,如 JavaDoc https://docs.oracle.com/javase/7/docs/api/java/nio html#write(java.nio.ByteBuffer)例如,处于非阻塞模式的套接字通道不能写入比套接字输出缓冲区中空闲的字节多的字节。Socket'sOutputStream根据定义是阻塞的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java