java网络编程中的read阻塞问题

Socket的可写状态和可读状态。当输出缓冲区未满时,Socket是可写的(注意,不是对方启用接收操作后,本地才能可写,这是错误的理解),因此,当套接字被建立时,即处于可写的状态。对于可读,则是指缓冲区中有接收到的数据,并且这些数据未完成处理。在socket创建时,并不处于可读状态,仅当连接的另一方向本套接字的通道写入数据后,本套接字方能处于可读状态(注意,如果对方套接字已经关闭,那么本地套接字将处于可读状态,并且每次调用read后,返回的都是-1)。

  • 服务器
import java.net.*;
import java.io.*;
public class  Server
{
    public static void main(String[] args) throws Exception
    {
        ServerSocket server = new ServerSocket(8888);
        System.out.println("Wait for connection...");
        Socket socket = server.accept();
        BufferedInputStream is = new BufferedInputStream(socket.getInputStream());
        byte[] buff = new byte[1024];
        int size;
        //当客户端的输出流没有close时,服务器端收不到-1,会一直在沉睡在while里面,
        while((size = is.read(buff)) != -1){
            String str = new String(buff,0,size);
            System.out.println(str);
            /****************************************************/
            if(str.indexOf(‘\n‘) > 0){//存在消息结束标志
                break;
            }
            /*****************************************************/
        }
        //is.close();
        System.out.println("Received");
        System.out.println("Sending...");
        BufferedOutputStream  out = new BufferedOutputStream(socket.getOutputStream());
        out.write("你好,我是服务器".getBytes());
        out.flush();
        out.close();
        is.close();
        socket.close();
        System.out.println("Send Over!");
    }
}
  • 客户端
import java.net.*;
import java.io.*;
public class  Client
{
    public static void main(String[] args) throws Exception
    {
        Socket socket = new Socket("localhost",8888);
        BufferedOutputStream  out = new BufferedOutputStream(socket.getOutputStream());
        /********************表示发送结束*****************************/
        out.write("你好,我是客户端\n".getBytes());
        out.flush();
        //out.close();有这句话时,服务器可以读到一个-1
        System.out.println("Send Over!");
        System.out.println("Receiving...");
        BufferedInputStream is = new BufferedInputStream(socket.getInputStream());
        byte[] buff = new byte[1024];
        int size;
        while((size = is.read(buff)) != -1){
            System.out.println(new String(buff,0,size));
        }
        is.close();
        out.close();
        socket.close();
        System.out.println("Received!");
    }
}

1、服务器侦听

2、客户端发送了连接请求,然后发送数据(未关闭连接);

3、服务器收到数据,但是读不到-1,陷入睡眠(客户端尾关闭连接,服务器读不到-1)

4、客户端收不到数据,也睡在了read里面

5、由于两者的沉睡,陷入了死循环

解决方法:

1、在客户端发送数据时,加一个结尾标志,服务器端检测这个标志

2、使用DataXXXStream封装数据流

时间: 2024-11-06 10:49:30

java网络编程中的read阻塞问题的相关文章

用java网络编程中的TCP方式上传文本文件及出现的小问题

自己今天刚学java网络编程中的TCP传输,要用TCP传输文件时,自己也是遇到了一些问题,抽空把它整理了一下,供自己以后参考使用. 首先在这个程序中,我用一个客户端,一个服务端,从客户端上传一个文本文件给服务端,服务端接收数据并显示“上传成功”给客户端. 客户端: 1 import java.io.BufferedReader; 2 import java.io.FileReader; 3 import java.io.IOException; 4 import java.io.InputStr

java网络编程中拿到源后的写入动作

在网络编程中的TCP传输里,拿到Socket的源后,应该怎么进行读写操作呢,下面我列举了两种方法,希望大家帮忙补充···· 1.利用byte数组作为一个缓冲区进行读写 1 //获取socket流,将图片上传给服务端 2 FileInputStream fis=new FileInputStream("c:\\12.jpg"); 3 4 //获取了输出流 5 OutputStream out=s.getOutputStream(); 6 7 //用数组作为缓冲 8 byte[]buf=n

java网络编程中Socket什么意思?怎么工作的?

连接的机制(套接字)(Socket)马克-to-win:同学,(视频下载) (全部书籍)请看看你自己的电视和什么连在一 起.是木桌子吗?还是窗帘?对,是接线板.网络的发明者们就是受到了我刚才提到的那个大家熟视无睹的现象的启发而采取了Socket(接线板)机制.但不 幸的是, 我们的最早的翻译家们不知什么原因,翻译成了套接字?谁能告诉我中文里套接字是什么意思?接线板(Socket)机制很形象.服务器和客户端都生成一个 Socket的类对象,俩对象就可以发送数据了.当然,机器之间的物理硬件以及电缆连

一站式学习Java网络编程 全面理解BIO/NIO/AIO完整版

一站式学习Java网络编程 全面理解BIO/NIO/AIO 资源获取链接:点击获取完整教程 网络层编程,是每一个开发者都要面对的技术.课程为解决大家学习网络层知识的难题,以创新性的“对比式学习”搭建网络编程课程,课程主线清晰(网络层基础铺垫-->java网络编程前置技术讲解-->阻塞式编程BIO-->非阻塞式编程NIO-->异步编程AIO-->综合实战)适合每一位需要理解网络编程的同学们学习.以“项目驱动”为导向的学习,与企业刚需灵魂契合. 适合人群 网络编程作为编程者的必备

Java基础篇Socket网络编程中的应用实例

说到java网络通讯章节的内容,刚入门的学员可能会感到比较头疼,应为Socket通信中一定会伴随有IO流的操作,当然对IO流比较熟练的哥们会觉得这是比较好玩的一章,因为一切都在他们的掌握之中,这样操作起来就显得非常得心应手,但是对于IO本来就不是多熟悉的哥们来说就有一定的困难了,在搞清楚IO流操作机制的同时还必须会应用到Socket通信中去,否则会对得到的结果感到非常郁闷和懊恼,下面就和大家一起分享一下自己遇到一点小麻烦后的感触以及给出的解决办法. 要求:客户端通过Socket通信技术上传本地一

Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO

Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO Java 非阻塞 IO 和异步 IO 转自https://www.javadoop.com/post/nio-and-aio 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO https://blog.csdn.net/column/details/21963.html 部分代码会放在我的的Github:https://github.com/h2p

Java网络编程和NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector

Java网络编程与NIO详解4:浅析NIO包中的Buffer.Channel 和 Selector 转自https://www.javadoop.com/post/nio-and-aio 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO https://blog.csdn.net/column/details/21963.html 部分代码会放在我的的Github:https://github.com/h2pl/ J

Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理

Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO https://blog.csdn.net/column/details/21963.html 部分代码会放在我的的Github:https://github.com/h2pl/ 浅谈 Linux

《Java网络编程核心技术详解》赶稿中......

<精通JPA与Hibernate:Java对象持久化技术详解>这本书写完,就开始着手写<Java网络编程核心技术详解>一书,已经写了一大半,内容包括:Java网络编程的基础知识. 套接字编程.非阻塞通信.创建HTTP服务器与客户程序.数据报通信.对象的序列化与反序列化.Java反射机制.RMI框架.JDBC API.JavaMail API.MVC设计模式.XML处理.安全网络通信.CORBA和Web服务. 每写一章,都会遇到一些挑战,主要是在调试程序时,没有出现预期的结果.例如分