一.概念
软件结构
C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件。
B/S结构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等。
两种架构各有优势,但是无论哪种架构,都离不开网络的支持。网络编程,就是在一定的协议下,实现两台计算机的通信的程序
一.服务器概念
服务器指一个管理资源并为用户提供服务的计算机软件
有一个计算机,不能叫服务器,只有装了服务器的软件才能叫服务器
二.通信三要素
1.协议:在传输数据的过程中需要遵守的规则
TCP:面向连接的协议(3次握手)
客户端---->服务端–>客户端向服务端请求连接
客户端<----服务端–>服务端告诉客户端可以连接
客户端---->服务端–>客户端直接连接服务端
通信效率慢,没有大小的限制
给两台计算机提供了一个可靠的通信,确保数据的完整性
UDP:面向无连接协议 QQ 通信效率快 传输数据的时候,有大小限制 64KB
不安全,容易丢失数据
发送视频(网络视频,直播,不用等待你是否到场,我照播不误)
2 .IP地址:每台计算机的唯一标识号 TCP协议中的标识号就是IP地址
IPV4:4个字节 --> 192.168.1.1
一个小数点代表一个字节,一个字节由8个二进制位转成十进制得来的,最大是255->42亿+
IPV6:16个字节,每一部分都是16进制—>比地球上的沙子都多(有点吹牛逼)
cmd命令:
ipconfig->查看自己的ip
ping ip地址或者域名
特殊地址:
127.0.0.1–>代表的本机ip 我自己
localhost
3 . 端口号:是每一个应用程序的唯一标识
范围0-65535 前1024已经被占用
二.实现简单客户端和服务端的交互
一.编写客户端
客户端:Socket
构造:
Socket(String host, int port)
host:连接服务端的ip地址
自己的计算机做服务器:127.0.0.1(localhost)
port:服务器设置的端口号
步骤:
1.创建Socket对象,指定要连接的服务器ip以及服务器设置的端口号
2.调用Socket中的getOutputStream获取OutputStream,往服务器上发请求(写数据)
3.调用Socket中国的getInputStream,读取服务端响应回来的结果(读数据)
4.关流
public static void main(String[] args) throws IOException {
//创建Socket对象,指定要连接的服务器ip以及服务器设置的端口号
Socket socket = new Socket("127.0.0.1",8888);
//调用Socket中的getOutputStream获取OutputStream,往服务器上发请求(写数据)
OutputStream outputStream = socket.getOutputStream();
outputStream.write("这是客户端发送的请求!".getBytes());
//调用Socket中国的getInputStream,读取服务端响应回来的结果(读数据)
InputStream inputStream = socket.getInputStream();
byte[] b = new byte[1024];
int len = inputStream.read(b);
System.out.println(new String(b,0,len));
//关流
inputStream.close();
outputStream.close();
socket.close();
}
二.编写服务端
服务端:ServerSocket:
构造:
ServerSocket(int port)
port:是服务器设置的端口号
方法:
Socket accept()–>等待接收连接服务端的客户端对象那个客户端连接我这个服务端,此方法返回的Socket对象就是哪个客户端的Socket对象
步骤:
1.创建ServerSoceket,设置自己的端口号
2.调用accept方法获取连接服务端的客户端对象
3.调用getInputStream用来读取客户端发来的请求数据(读数据)
4.调用getOutputStream往客户端响应一条数据(写数据)
5.关闭资源
public static void main(String[] args) throws IOException {
//创建ServerSoceket,设置自己的端口号
ServerSocket serverSocket = new ServerSocket(8888);
//调用accept方法获取连接服务端的客户端对象
Socket accept = serverSocket.accept();
//调用getInputStream用来读取客户端发来的请求数据(读数据)
InputStream inputStream = accept.getInputStream();
byte[] b = new byte[1024];
int len = inputStream.read(b);
System.out.println(new String(b,0,len));
//调用getOutputStream往客户端响应一条数据(写数据)
OutputStream outputStream = accept.getOutputStream();
outputStream.write("这是服务器返回的数据".getBytes());
//关闭资源
outputStream.close();
serverSocket.close();
inputStream.close();
accept.close();
}
三.文件上传案例
一.编写客户端
步骤:
1.创建Socket对象,指定服务端的ip以及端口号
2.创建FileInputStream用于读取硬盘上的图片
3.调用getOutputStream用于往服务端写我们读到的图片
4.边读边写
5.调用getInputStream.接收服务端响应回来的结果
6.关闭资源
public static void main(String[] args) throws IOException {
//创建Socket对象,指定服务端的ip以及端口号
Socket socket = new Socket("127.0.0.1",9999);
//创建FileInputStream用于读取硬盘上的图片
FileInputStream fis = new FileInputStream("E:\\壁纸\\01.jpg");
//调用getOutputStream用于往服务端写我们读到的图片
OutputStream os = socket.getOutputStream();
//边读边写
byte[] b = new byte[1024];
int len = 0;
while ((len = fis.read(b)) != -1){
os.write(b,0,len);
}
//通知服务端,我不写数据了,你别等着了,你继续往下执行吧
socket.shutdownOutput();
//调用getInputStream.接收服务端响应回来的结果
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
int read = is.read(bytes);
System.out.println(new String(bytes,0,read));
//关闭资源
is.close();
os.close();
fis.close();
socket.close();
}
二.编写服务端:(多线程版)
步骤:
1.创建ServerSocket对象,设置端口号
2.调用accept方法,等待接收连接过来的客户端对象
3.调用getInputStream.读取客户端歇过来的图片
4.创建FileOutputStream对象,往硬盘上的指定位置写图片数据
5.边读边写
6.调用getOputStream往客户端写数据->响应一个"文件上传成功"
7.关闭资源
Address already in use: JVM_Bind异常原因:连续来了2次服务器(端口号被占用)
public static void main(String[] args) throws IOException {
//创建ServerSocket对象,设置端口号
ServerSocket serverSocket = new ServerSocket(9999);
while (true){
new Thread(new Runnable() {
Socket accept;
InputStream is;
FileOutputStream fos;
OutputStream os;
@Override
public void run() {
try {
//调用accept方法,等待接收连接过来的客户端对象
accept = serverSocket.accept();
//调用getInputStream.读取客户端歇过来的图片
is = accept.getInputStream();
//创建FileOutputStream对象,往硬盘上的指定位置写图片数据
String name = System.currentTimeMillis()+".jpg";
fos = new FileOutputStream("E:\\HeiMa\\"+name);
//边读边写
byte[] b = new byte[1024];
int len = 0;
while ((len = is.read(b)) != -1){
fos.write(b,0,len);
}
//调用getOputStream往客户端写数据->响应一个"上传成功"
os = accept.getOutputStream();
os.write("上传成功".getBytes());
}catch (Exception e){
e.printStackTrace();
}finally {
try {
//关闭资源
if(os != null) os.close();
if(fos != null) fos.close();
if(is != null) is.close();
if(accept != null) accept.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
}