TCP通信中的readLine()方法遇到的问题

TCP通信中的readLine()

Server.java

ServerSocket ss=new ServerSocket(10086);
Socket s=ss.accept();
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
//		封装目的地文本文件
		BufferedWriter bw=new BufferedWriter(new FileWriter("copy.java",true));
		String line =null;
//		读取客户端数据并将其写入文本文件
		while((line=br.readLine())!=null) {
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
//		提供一个反馈表示文件上传成功
		BufferedWriter bwServer=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		bwServer.write("文件上传成功!");
		bwServer.flush();
		bwServer.close();

Client.java

BufferedReader br=new BufferedReader(new FileReader("InterfaceTest.java"));
		BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		String line =null;
//		读取客户端文件的数据
		while((line=br.readLine())!=null) {
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
//		接受反馈
		BufferedReader brClient=new BufferedReader(new InputStreamReader(s.getInputStream()));
		String Client=brClient.readLine();
		System.out.println(Client);
		brClient.close();

在TCP通信的实例中,向服务器端上传一个文件,当上传完成时,想让服务器给我一个反馈“文件上传成功!”,但是会发现一个问题:文件能上传成功,但是反馈一直接收不到,程序为堵塞状态!

发现是readLine()的问题:分为两种情况

  1. 在文本文件格式下:

    读取一个文本行。当读取到“\r”或者"\n"才会返回结果,返回的结果中并没有(\r ,\n)。这就是读取一行的意思。什么时候返回null呢?当读取到文件末尾的时候才会返回null!(这里和通信过程中的readLine不一样)

  2. Socket通信中:

    在TCP通信中,我想要的是服务器读取完文件给我一个反馈,但是这里当服务器读取完数据后,并不会返回NULL,也是就说吧,无法跳出while循环,他会一直堵塞在这!实际上readLine()是一个阻塞函数,当数据读取完之后他不会返回null!为什么? **因为这里readLine()读取的并不是文本文件!**它读取的是通道(TCP通信必须先建立通道)中的流数据

    BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
    

    所以它并不会返回NULL,br不知道已经没有数据,br会一直等着客户端发送数据,但是客户端数据已经发送完毕,等着服务器给反馈,两个相互等待!

如何解决?

​ shutdownOutput(),在Client.java中的while循环后面调用此方法!

public void shutdownOutput()throws IOException
禁用此套接字的输出流。对于 TCP 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。 如果在套接字上调用 shutdownOutput() 后写入套接字输出流,则该流将抛出 IOException。

这里的终止序列(-1)告诉Server中的输入流,已经没有数据了,(readLine读到这里返回null)这样server才会继续下面的操作!

关于shutdownOutput方法

​ Client

s.shutdownOutput();
System.out.println(s.isOutputShutdown());//true
System.out.println(s.isConnected());//true

​ Server

System.out.println(s.isOutputShutdown());//false
System.out.println(s.isConnected());//true

上面的代码表示:

  1. 关闭是单向性的!(Client调用的并不会影响到Server)
  2. 只关闭流对象,并不会关闭Socket连接(close全部关闭)

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值