/**
* 文件上传客户端,读取本地文件,上传给服务器
*
* 数据源:本地文件
*目的:服务器
*
*步骤:
* 1.创建客户端对象
* 2.获取本地文件输入流读取到Byte数组中
* 3.获取socket文件输出流 上传到服务器中
* 4.获取socket文件输入流回显服务器返回的信息,打印
* 5.关闭资源
*/
public class Client {
public static void main(String[] args) throws IOException {
//1.创建客户端对象
Socket socket = new Socket("127.0.0.1", 8888);
//2.获取本地文件输入流读取到Byte数组中
File file = new File("E:\\data\\project\\tcp-study\\clientImg\\1596592777(1).jpg");
FileInputStream is = new FileInputStream(file);
byte[] bytes = new byte[1024];
int len=0;
//3.获取socket文件输出流 上传到服务器中
OutputStream os = socket.getOutputStream();
while ((len=is.read(bytes))!=-1){
os.write(bytes,0,len);
}
//4.获取socket文件输入流回显服务器返回的信息,打印
InputStream socketInputStream = socket.getInputStream();
while ((len=socketInputStream.read(bytes))!=-1){
System.out.println(new String(bytes, 0, len));
}
//5.关闭资源
socketInputStream.close();
os.close();
is.close();
socket.close();
}
}
/**
* 文件上传服务器,获取客户端上传的文件,保存在本地中
*
* 步骤:
* 1.获取服务器对象
* 2.获取socket对象
* 3.根据socket获取客户端输入流
* 4.读取输入流,同时用本地输出流输出到本地文件夹中保存
* 5.获取socket输出流输出保存成功的信息给客户端
* 6.关闭资源
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.获取服务器对象
ServerSocket serverSocket = new ServerSocket(8888);
//2.获取socket对象
Socket socket = serverSocket.accept();
//3.根据socket获取客户端输入流
InputStream socketInputStream = socket.getInputStream();
//4.读取输入流,同时用本地输出流输出到本地文件夹中保存
byte[] bytes = new byte[1024];
int len =0;
File file = new File("E:\\data\\project\\tcp-study\\serverImg");
//如果文件夹不存在,则创建
if (!file.exists()){
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file+File.separator+"1.jpg");
while ((len=socketInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}
//5.获取socket输出流输出保存成功的信息给客户端
OutputStream socketOutputStream = socket.getOutputStream();
socketOutputStream.write("保存成功".getBytes());
//6.关闭资源
socketOutputStream.close();
socketInputStream.close();
fileOutputStream.close();
socket.close();
serverSocket.close();
}
}
但是这样写文件会实现上传功能,但是程序会进入阻塞状态因为在客户端代码中,while ((len=is.read(bytes))!=-1)
客户端读取到文件的末尾,但是不告诉服务器已经结束了,结果服务器一直在等,不发送保存成功的信息,导致客户端也在等,所以客户端和服务器都进入阻塞状态。
在客户端while ((len=is.read(bytes))!=-1) 后,使用socket.shutdownOutput();告诉服务器已经结束了。
/**
* 文件上传客户端,读取本地文件,上传给服务器
*
* 数据源:本地文件
*目的:服务器
*
*步骤:
* 1.创建客户端对象
* 2.获取本地文件输入流读取到Byte数组中
* 3.获取socket文件输出流 上传到服务器中
* 4.获取socket文件输入流回显服务器返回的信息,打印
* 5.关闭资源
*/
public class Client {
public static void main(String[] args) throws IOException {
//1.创建客户端对象
Socket socket = new Socket("127.0.0.1", 8888);
//2.获取本地文件输入流读取到Byte数组中
File file = new File("E:\\data\\project\\tcp-study\\clientImg\\1596592777(1).jpg");
FileInputStream is = new FileInputStream(file);
byte[] bytes = new byte[1024];
int len=0;
//3.获取socket文件输出流 上传到服务器中
OutputStream os = socket.getOutputStream();
while ((len=is.read(bytes))!=-1){
os.write(bytes,0,len);
}
//告诉服务器结束了
socket.shutdownOutput();
//4.获取socket文件输入流回显服务器返回的信息,打印
InputStream socketInputStream = socket.getInputStream();
while ((len=socketInputStream.read(bytes))!=-1){
System.out.println(new String(bytes, 0, len));
}
//5.关闭资源
socketInputStream.close();
os.close();
is.close();
socket.close();
}
}
/**
* 文件上传服务器,获取客户端上传的文件,保存在本地中
*
* 步骤:
* 1.获取服务器对象
* 2.获取socket对象
* 3.根据socket获取客户端输入流
* 4.读取输入流,同时用本地输出流输出到本地文件夹中保存
* 5.获取socket输出流输出保存成功的信息给客户端
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.获取服务器对象
ServerSocket serverSocket = new ServerSocket(8888);
while (true){
//2.获取socket对象
Socket socket = serverSocket.accept();
//3.根据socket获取客户端输入流
InputStream socketInputStream = socket.getInputStream();
//4.读取输入流,同时用本地输出流输出到本地文件夹中保存
byte[] bytes = new byte[1024];
int len =0;
//自定义命名规则,防止重名
String fileName="laowang"+System.currentTimeMillis()+ new Random().nextInt(9999)+".jpg";
File file = new File("E:\\data\\project\\tcp-study\\serverImg");
//如果文件夹不存在,则创建
if (!file.exists()){
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file+File.separator+fileName);
while ((len=socketInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}
//5.获取socket输出流输出保存成功的信息给客户端
OutputStream socketOutputStream = socket.getOutputStream();
socketOutputStream.write(("保存成功,url为:"+file.getCanonicalPath()+fileName).getBytes());
}
}
}
/**
* 文件上传服务器,获取客户端上传的文件,保存在本地中
*
* 步骤:
* 1.获取服务器对象
* 2.获取socket对象
* 3.根据socket获取客户端输入流
* 4.读取输入流,同时用本地输出流输出到本地文件夹中保存
* 5.获取socket输出流输出保存成功的信息给客户端
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.获取服务器对象
ServerSocket serverSocket = new ServerSocket(8888);
while (true){
//2.获取socket对象,获取到一个,就开一条线程去执行,提高效率
Socket socket = serverSocket.accept();
//使用多线程提高效率
new Thread(()->{
try {
//3.根据socket获取客户端输入流
InputStream socketInputStream = socket.getInputStream();
//4.读取输入流,同时用本地输出流输出到本地文件夹中保存
byte[] bytes = new byte[1024];
int len =0;
//自定义命名规则,防止重名
String fileName="laowang"+System.currentTimeMillis()+ new Random().nextInt(9999)+".jpg";
File file = new File("E:\\data\\project\\tcp-study\\serverImg");
//如果文件夹不存在,则创建
if (!file.exists()){
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file+File.separator+fileName);
while ((len=socketInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}
//5.获取socket输出流输出保存成功的信息给客户端
OutputStream socketOutputStream = socket.getOutputStream();
socketOutputStream.write(("保存成功,url为:"+file.getCanonicalPath()+fileName).getBytes());
//6.关闭
socketOutputStream.close();
fileOutputStream.close();
socketInputStream.close();
socket.close();
}catch (Exception e){
System.out.println(e);
}
}).start();
}
}
}
/**
*基于TCP协议的B/S架构服务端
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.获取服务器对象
ServerSocket serverSocket = new ServerSocket(8888);
//2.获取客户端socket对象
Socket socket = serverSocket.accept();
//3.读取客户端发送过来的请求
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
int len =0;
while ((len=is.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
//关闭资源
is.close();
serverSocket.close();
socket.close();
}
}
浏览器发起请求:http://localhost:8888/tcp-study/web/1.jpg
结果:
可以看到,读取出来的报文是这样的,我们就可以截取圈出来的字符串,把对应的文件写如客户端IO流中,完成!
代码如下:
/**
* 给予TCP协议的B/S架构服务端
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.获取服务器对象
ServerSocket serverSocket = new ServerSocket(8888);
while (true){
//2.获取客户端socket对象
Socket socket = serverSocket.accept();
new Thread(()->{
try {
//3.读取客户端发送过来的请求
//读取一行足,即把文件输入流,包装成换成字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//读取一行
String line = null;
try {
line = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
//根据空格分割,然后去除最开始的/,结果为:tcp-study/web/1.jpg
String[] split = line.split(" ");
String url=split[1].substring(1);
System.out.println("访问url:"+url);
//用本地流读取该路径下文件,写入到客户端流
FileInputStream is = new FileInputStream(url);
byte[] bytes = new byte[1024];
int len=0;
//写入http响应头,才可以被浏览器解析
OutputStream os = socket.getOutputStream();
os.write("HTTP/1.1 200 OK\r\n".getBytes());
os.write("Content-Type:text/html\r\n".getBytes());
os.write("\r\n".getBytes());
while ((len=is.read(bytes))!=-1){
//写出去
os.write(bytes,0,len);
}
//关闭资源
socket.close();
os.close();
is.close();
reader.close();
}catch (Exception e){
System.out.println(e);
}
}).start();
}
}
}
请求:http://localhost:8888/web/hello.html
结果: