繁体   English   中英

通过同一个套接字发送和接收

[英]Send and receive over the same socket

我是Java套接字的新手,我在使用相同的套接字发送和接收数据时遇到了问题。

服务器位于Android设备上:

    ServerSocket listenSocket = null;
    OutputStream dataOutStream = null;
    Socket socket = null;
    InputStream dataInputStream = null;

    // Listen
    System.out.println("Start listening");
    try {
        listenSocket = new ServerSocket(4370);
        socket = listenSocket.accept();
        System.out.println("Connection accepted");
        dataInputStream = socket.getInputStream();
        dataOutStream = socket.getOutputStream();
        while (dataInputStream.read() != -1);
    } catch (IOException e) {
        e.printStackTrace();
        close(listenSocket, socket);
        return;
    }

    // Answer
    System.out.println("Answering...");
    byte[] answer = {(byte) 0x82, (byte) 0xf8, 0, 0};
    try {
        dataOutStream.write(answer);
    } catch (IOException e) {
        e.printStackTrace();
        close(listenSocket, socket);
        return;
    }

    close(listenSocket, socket);
    System.out.println("Finished");

客户端在带有Java 6的Linux机器上运行:

    Socket socket = new Socket("192.168.1.33", 4370);
    OutputStream dataOutputStream = socket.getOutputStream();
    InputStream dataInputStream = socket.getInputStream();
    byte[] bufferOut = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    dataOutputStream.write(bufferOut);
    System.out.println("Sent");

    while (dataInputStream.read() != -1);       
    socket.close();
    System.out.println("Finished");

这里的问题是服务器卡住了while (dataInputStream.read() != -1); 线。 看起来客户端永远不会关闭发送。

如果我在客户端部分中执行dataOutputStream.close() (当然,在编写之后),那么它确实有效,但随后客户端就会死掉while (dataInputStream.read() != -1); 说插座已关闭。

我希望保持整个套接字打开,以便在同一个套接字上进行更多数据交换,直到发送关闭命令。

我在这里做错了什么,有什么见解吗? 提前致谢!

你既不关闭套接字也不关闭输出流。 您在客户端执行shutdownOutput()

...
dataOutputStream.write(bufferOut);
System.out.println("Sent");
socket.shutdownOutput();
...

这称为半关闭,因为它只关闭一个方向并使另一个方向打开。

编辑 :奥拉夫展示了一种内置的方式来实现问题中的请求 - 响应场景。

关闭从套接字获取的流也会关闭套接字( 另请参阅 )。另一方面,只要流/套接字打开,从套接字获取的InputStream就不可能查看是否所有数据都已发送(可能在它的路上更多的位!)。 除非使用Olafs示例,否则双向通信无法以这种方式工作。 这允许等待服务器响应。

您可以做的是自己定义一个结束信号(例如字符串“END”),并且任何一方都会监听,直到读取该结束信号,然后写入。 但是这会带来你遇到的各种其他问题(如果发送的文本中包含结束信号怎么办?如果伙伴在发送结束之前死了怎么办?超时?...)。 也可以看看

我会尝试查看Java中支持的SOAP或RESTful服务(但我不知道在Android上有多好)。 通常,有许多库可以帮助您解决这些问题,并使您免受低级网络的影响。 使用现有解决方案几乎总能带来回报。

尝试通过执行dataOutStream.flush()刷新OutputStream

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM