在学习socket的TCP通讯
在使用 TCP传一个文件时 遇到这样两个问题
1. 服务端流读取时一次性读了所有内容 而不是分行读取
2. 自动刷新不生效
代码如下
package com.fuge.TCP.demo2;
import java.io.*;
import java.net.Socket;
public class UploadClient {
public static void main(String[] args) throws IOException {
//1. 建立tcp客户端socket
Socket socket = new Socket("127.0.0.1", 6060);
//2. 文件读取流
BufferedReader bufr = new BufferedReader(new FileReader("D://test.txt"));
//3. TCP文件输出流
// 设置了自动刷新 然没有生效
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
String line;
// 循环读文件然后通过TCP输出
while ((line = bufr.readLine()) != null) {
out.write(line);
/**
* 这里自动刷新不生效 需要手动刷新
*/
out.flush();
}
// 结束标志
socket.shutdownOutput();
// 读取服务端返回的内容
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String returnMsg = in.readLine();
System.out.println(returnMsg);
//关闭流
bufr.close();
socket.close();
}
}
package com.fuge.TCP.demo2;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class UploadServer {
public static void main(String[] args) throws IOException {
// 1. 建立服务端TCP服务
ServerSocket ss = new ServerSocket(6060);
// 获取连接的客户端的socket
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress() + "............connection!!!");
// 建立文件读取流
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
// 建立文件写出流 写到D盘中去
BufferedWriter bw = new BufferedWriter(new FileWriter("D://new.txt"));
String line;
while ((line = in.readLine()) != null) {
bw.write(line);
/**
* 这里换行不生效
* 因为debug时发现 这里的line是一次性读了所有的内容 而不是一段一段读取的
*/
bw.newLine();
bw.flush();
}
// 返回一个成功标志给客户端 设置了自动刷新
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
out.write("上传成功");
out.flush(); // 这里自动刷新不生效 需要手动刷新
//关闭流
bw.close();
s.close();
ss.close();
}
}
首先
flush
方法,并不保证将字节流写到物理网络,或者写到物理磁盘,而是将他们写到操作系统的缓冲区。这一点从flush
方法的API
可以看出。其次这里你用到的是Socket
,flush
方法会将字节流写到Socket
发送缓冲区,为了减少网络资源的消耗,操作系统会将你多次flush
的内容装成一组报文发出去,所以你在server
端只用接收一次。至于
autoFlush
,你看看API
就知道了,它只有在调用println()
,printf()
,format()
方法后有效,write()
是无效的。