C/S例子
C/S模式称为客户端/服务器模式
实例:
客户端上传文件到服务器,服务器接收后保存到服务器硬盘上
重点注意
1.分清楚本地流和网络流,网络流都通过Socket获取,服务器通过获取客户端的Socket来获得网络流
2.注意客户端在本地输入流获取图片时跳过了结束标志,导致发给服务器是没有结束标志的,用shutdownOutput()方法给服务器一个结束标志
代码实现
客户端
package demo_NET;
import java.io.*;
import java.net.Socket;
/*实例:
客户端上传文件到服务器,服务器接收后保存到服务器硬盘上
*/
public class ep_TCPClient {
public static void main(String[] args) throws IOException {
//创建客户端本地字节输入流,这里我用字节输入缓冲流
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("D:\\clientpic\\1.jpg"));
//创建客户端连接服务器的套接字
Socket socket=new Socket("127.0.0.1",8888);
//用套接字获取字节输出流和字节输入流
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
//本地字节输入流获取信息,并写入网络字节输出流给服务器
int len=0;
byte []bytes=new byte[1024];
while((len=bis.read(bytes))!=-1){
os.write(bytes,0,len);
}
System.out.println("客户端:上传成功!");
//给服务器写一个结束标记
socket.shutdownOutput();
//网络字节输入流开启,等待服务器回传信息
len=0;
bytes=new byte[1024];
while((len=is.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
os.close();
is.close();
bis.close();
socket.close();
}
}
服务器
package demo_NET;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
/*实例:
客户端上传文件到服务器,服务器接收后保存到服务器硬盘上
*/
public class ep_TCPServer {
public static void main(String[] args) throws IOException {
//创建服务器对象
ServerSocket server=new ServerSocket(8888);
//让服务器一直工作
while(true){
Socket s1 = server.accept();
new Thread(new Runnable() {
@Override
public void run() {
try{
//获得客户端的套接字,并定义网络字节输出流和网络字节输入流
InputStream is = s1.getInputStream();
OutputStream os = s1.getOutputStream();
//判断该文件夹是否存在,不存在就创建
File file=new File("D://serverpic");
if(!file.exists()){
file.mkdirs();
}
//自定义文件的命名规则:防止同名文件覆盖。规则:毫秒值+随机数
String filename=System.currentTimeMillis()+new Random().nextInt(999999)+".jpg";
//创建本地字节输出流,这里使用字节输出缓冲流
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(file+"\\"+filename));
//利用网络字节输入流获得客户端传过来的文件,写入到服务器的硬盘中去
int len=0;
byte[] bytes=new byte[1024];
while((len=is.read(bytes))!=-1){
bos.write(bytes,0,len);
}
System.out.println("服务器:写入服务器硬盘成功!");
//给客户端回传信息
os.write("服务器:客户端,我收到你发来的文件了".getBytes());
//关闭资源
s1.close();
bos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}).start();
}
// server.close();
}
}
B/S例子
B/S模式称为浏览器/服务器模式
实例:
浏览器访问服务器文件,服务器接收信息后回传文件给浏览器
重点注意
1.获得浏览器的请求信息后,可拆分信息获取浏览器想要访问的文件
2.当请求的html网页中有不同的资源文件时,浏览器是不断请求的状态,所以需要将服务器一直开启监听状态
3.这里最好使用IE浏览器来访问服务器,用其他浏览器经常失败
代码实现
我的文件结构
浏览器端
通过IE浏览器访问网页
这是我的访问地址:http://127.0.0.1:8080/绝对路径
服务器
package demo_NET;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//实现浏览器访问服务器
public class ep2_TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket server=new ServerSocket(8080);
while(true){
Socket s1 = server.accept();
new Thread(new Runnable() {
@Override
public void run() {
try{
InputStream is = s1.getInputStream();
//把网络输入流转换成字符缓冲输入流
BufferedReader br=new BufferedReader(new InputStreamReader(is));
/*获取到的字符信息为 GET /demo/src/demo_NET/web/111.html HTTP/1.1
用split方法把/demo/src/demo_NET/web/111.html提取出来
*/
String []arr=br.readLine().split(" ");
//去掉前面的‘/’
String htmlpath=arr[1].substring(1);
FileInputStream fis=new FileInputStream(htmlpath);
OutputStream os = s1.getOutputStream();
//写入HTTP协议响应头,固定写法
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();
s1.close();
}catch (IOException e){
e.printStackTrace();
}
}
}).start();
}
//server.close();
}
}
html网页
自己随便写一个就好了
这里我提供一下最简陋的网页,建个img文件夹后把自己的两张图片放进去,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style>
div{
width:500px;
height:500px;
}
div img{
width:100%;
height:100%;
}
</style>
</head>
<body>
<div>
<img src="img/a.jpg" />
<div style="text-align:center">
<h1>图片1</h1>
</div>
<img src="img/b.jpg" />
<div style="text-align:center">
<h1>图片2</h1>
</div>
</div>
</body>
</html>