引言:
网络基础入门
文件上传
B\S通信
文件上传
明确:
- 数据源
- 目的地
客服端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| FileInputStream fis = new FileInputStream("D:\\a.txt");
Socket socket = new Socket("127.0.0.1",8888);
OutputStream os = socket.getOutputStream();
int len = 0; byte[] bytes = new byte[1024]; while ((len = fis.read(bytes))!=-1){
os.write(bytes,0,len); }
InputStream is = socket.getInputStream();
while ((len = is.read(bytes))!=-1){
System.out.println(new String(bytes,0,len)); } fis.close(); socket.close();
|
服务器端
明确:
- 数据源:客户上传的文件
- 目的地:服务器的硬盘的某一个位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| ServerSocket server = new ServerSocket(8888);
Socket socket = server.accept();
InputStream is = socket.getInputStream();
File file = new File("D:\\upload"); if (!file.exists()) { file.mkdirs(); }
FileOutputStream fos = new FileOutputStream(file + "a.txt");
int len = 0; byte[] bytes = new byte[1024]; while ((len = is.read(bytes)) != -1) {
fos.write(bytes, 0, len); } socket.getOutputStream().write("上传成功".getBytes());
fos.close(); socket.close(); server.close();
|
运行服务器端和客户端,发现服务器端与客户端并没有停止下来,但是文件已经上传了
其实是因为FileInputStream中的read方法,当其没有可输入时,此方法会阻塞
read方法永远也读取不到文件的结束标记
因为我们没有写结束标记,读取不到就会进入阻塞状态,进入死循环
解决方法:
上传完文件,给服务器写一个结束标记,void shutdownOutput()
,禁用此套接字的输出流,任何以前写的数据都会被发送并且文件会正常结束
文件上传优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| ServerSocket server = new ServerSocket(8888);
while (true) { Socket socket = server.accept(); new Thread(new Runnable() { @Override public void run() { try{ InputStream is = socket.getInputStream(); File file = new File("D:\\upload"); if (!file.exists()) { file.mkdirs(); } String fileName = "域名" + System.currentTimeMillis() + new Random().nextInt(9999) + ".txt"; FileOutputStream fos = new FileOutputStream(file + "\\" + fileName); int len = 0; byte[] bytes = new byte[1024]; while ((len = is.read(bytes)) != -1) { fos.write(bytes, 0, len); } socket.getOutputStream().write("上传成功".getBytes()); fos.close(); socket.close(); } catch (IOException e){ System.out.println(e); } } }).start(); }
|
模拟B\S服务器
客户端不再是Java程序,而是一个web页面
服务器端
1 2 3 4 5 6 7 8 9 10
| ServerSocket server = new ServerSocket(8080);
Socket socket = server.accept(); 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)); }
|
网页地址输入
1
| http://127.0.0.1:8080/项目名目录地址/index.html
|
服务端打印
1 2 3 4 5 6 7 8 9 10 11 12
| GET /day04-code/src/index.html HTTP/1.1 Host: 127.0.0.1:8080 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36 Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Sec-Fetch-Site: none Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
|
服务器端要响应用户的信息,回应一个html页面,我们需要读取index文件必须知道这个文件的地址,二者地址就是请求信息的第一行
1
| GET /day04-code/src/index.html HTTP/1.1
|
我们可以使用BufferedReader
的readLine
读取该一行,用String类的split(" ")
切割字符串,得到
1
| /day04-code/src/index.html
|
再使用String类的subString(1)
获取html文件的路径
1
| day04-code/src/index.html
|
这样就得到了路径
服务器创建一个本地的字节输入流,根据获取到的文件路径,获取html文件,并写入固定三行代码
1 2 3 4 5
| os.write("HTTP/1.1 200 OK\r\n".getBytes()); os.write("Content-Type:text/html\r\n".getBytes());
os.write("\r\n".getBytes());
|
服务器端使用网络字节输出流把读取到的文件写到客户端
实现代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| ServerSocket server = new ServerSocket(8080); while (true) { Socket socket = server.accept(); new Thread(new Runnable() { @Override public void run() { try { InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line = br.readLine(); String[] arr = line.split(" "); String htmlPath = arr[1].substring(1); FileInputStream fis = new FileInputStream(htmlPath); 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()); int len = 0; byte[] bytes = new byte[1024]; while ((len = fis.read(bytes)) != -1) { os.write(bytes, 0, len); } fis.close(); socket.close(); } catch (IOException e) { System.out.println(e); } } }).start(); }
|