java - 套接字数据似乎没有到达客户端

标签 java sockets

我已经编写了一些服务器端套接字处理代码,但我担心我的数据包可能并不总是返回到客户端。我正在记录我的所有事件,在我的日志文件中它说我正在发送信息。但是客户端也在记录事件,并且在他们的日志中他们说他们没有收到任何东西。

我发送数据的代码如下:

public void write(Packet packet) {
    String data = packet.serialize();
    log("Send=[" + data + "]", "Write"); // log to file

    try {
        _writer.write(data);
        _writer.flush();
    } catch (Exception ex) {
        log(ex, "write");
    }
}

每个套接字都在一个新线程上创建,我像这样立即创建我的作者和读者(在公共(public)运行方法中):

// _sockt is a Java Socket object
_writer = new BufferedWriter(new OutputStreamWriter(_socket
                    .getOutputStream()));
            _reader = new SocketReader(_socket);

SocketReader 只是我为监听响应而创建的一个包装类,它有一个公共(public)读取方法,如下所示:

public String read() throws IOException, SocketTimeoutException {

    _socket.setSoTimeout(_timeOut);

    if(_reader == null)
        _reader = new BufferedReader(new InputStreamReader(_socket.getInputStream()));

            // read from the stream
    return new PacketDataInputStream(_reader).read();
}

PacketDataInputStream 包装类:

BufferedReader _reader = null;

public PacketDataInputStream(BufferedReader reader)
{
    _reader = reader;
}

public String read() throws IOException, SocketException {

    StringBuilder builder = new StringBuilder();
    int c = 0;

    while((c = _reader.read()) != -1)
    {
        char ch = (char)c;

        builder.append(ch);

        if(ch == PacketConstants.ETX)
            break;
    }

    if(builder.length() > 0)
        return builder.toString();
    else
        return null;

}

我认为我创建实际套接字监听器对象的方式非常标准:

InetAddress address = InetAddress.getByName(IP);
        server = new ServerSocket( port, 0, address);

                    // My own manager class to handle all the sockets connected 
        WebSocketManager manager = new WebSocketManager(this);

        Socket connection = null;

        while(bContinue)
        {
            connection = server.accept();

            if(bContinue) {
                                    // assign the socket to a new thread and start
                                    // that thread
                manager.newSocket(connection);  
            } else {
                connection.close();
            }
        }
  • 有没有可能是我使用了错误的对象来发回数据。
  • 我什至应该使用缓冲写入器和读取器吗?我原以为这些是最好的方法,但现在我不太确定了。

请务必注意,这种情况不会一直发生,只是偶尔发生。可能是客户代码有错误,但我需要确保在返回给他们之前我做的是正确的。

此代码在 Linux Ubuntu 服务器上运行。记录发生在一个文本文件中,那里没什么特别的。我的日志文件显示返回客户端的 Send="" 数据没有异常,所以看起来好像 .write 和 .flush() 有效?套接字连接是持久的,仅由客户端和/或网络问题关闭。

更新 ----- 客户端代码 --------:

我确实设法获得了一些客户端代码,以了解它们如何处理数据的发送和接收(以防万一在它们端更明显)。客户端实际上是通过 Android 设备 连接到此服务器(如果有帮助的话)。

创建套接字

static final int BUFFER_SIZE = 20000;       // Maximum packet size

java.net.InetAddress server = java.net.InetAddress.getByName(url);
socket = new Socket(server, port);
// Set socket options:
socket.setReceiveBufferSize(BUFFER_SIZE);
socket.setSendBufferSize(BUFFER_SIZE);
socket.setKeepAlive(true);
socket.setTcpNoDelay(true);

发送:

try {
            // Send the packet:
        OutputStream stream = socket.getOutputStream();
        stream.write(p.getByteArray ());
        stream.flush();

            // Update the time:
        lastPacketSendTime = new Date ();
    } catch (IOException e) {
        setError("Error sending packet (" + e.getMessage() + ")", ERROR_IO);
        return false;
    }

接收:

socket.setSoTimeout(timeout);
            // Get the reader:
        inputStream = socket.getInputStream();



     while (true) {
                    // Get the next character:
                int value = inputStream.read();
                    // Check for -1, indicating that the socket is closed:
                if (value == -1) {
                        // The socket is closed remotely, so close it locally as well:
                    disconnect();
                    inputStream = null;
                    return null;
                }
                                // ... and a bunch of other stuff to handle the actual data

                        }

11 月 14 日编辑: 现在这实际上被证明是一个更大的问题。客户端日志和服务器日志似乎都在发送。但有时数据似乎没有通过,或者即使有,有时也会延迟 10 - 30 - 60 秒。

如果需要,我可以提供更多信息。

最佳答案

当您使用 BufferedReaders 和 BufferedWriters 时,事情会被缓冲。直接使用输入和输出流怎么样。另外,writer 是基于字符的,我不知道你是否需要发送二进制数据,但如果需要,这对 writer 来说是个问题。

关于java - 套接字数据似乎没有到达客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11154055/

相关文章:

java - 在 do-while 循环中使用 JSoup,仍然抛出异常

C++ 通过 UDP 套接字发送结构

sockets - Haskell 中的原始套接字

未收到 Internet 上的 Python 套接字

java - 如何将输入传递到 Kubernetes 容器内的 Java 应用程序?

java - RandomIterator 不产生随机输出

java - 安卓测试套件 : Include all TestCases except some explicitly defined

java - 如何从像素绘制 3D 对象?

c# - 通过 Socket 直接使用 TcpClient 有什么好处?

sockets - 网络发现应用程序使用哪个端口