1. 服务器端启动
2. 等待客户端发起连接请求
3. 建立逻辑连接后,该逻辑连接中包含一个IO对象
4. 该IO对象是一个字节流传输对象
5. 服务器端必须明确的两件事:
a. 服务器与多个客户端进行交互时,服务器必须明确当前是和哪个客户端交互
可以使用服务器端的accept方法获取请求的客户端对象
b. 服务器端是没有流对象的,它时通过获取请求的客户端对象Socket
使用获取到达Socket对象中的IO流与该对象进行通信
使用该对象的字节输入流读取客户端发送的数据
使用该对象的字节输出流给客户端回数据
Socket/ServerSocket
1. 表示客户端的类:Socket
2. 表示服务器端的类:ServerSocket
3. Socket:
a. 构造方法:
Socket(String host,int port);//传入服务器端的IP地址和端口号
b. 重要成员方法:
OutputStream getOutputStream();//获取输出流对象
InputStream getInputStream();//获取输入流对象voidclose();//关闭该套接字
c. 使用方法:
1. 传入服务器端IP和端口号,创建客户端Socket对象
2. 获取客户端的输出流OutputSream对象
3. 使用OutputStream对象的write方法,将数据发送给服务器端
4. 获取客户端的输入流InputStream对象
5. 使用InputStream对象的read方法,读取客户端发送的数据
6. 关闭Socket,释放对象。
d. 注释事项:
1. 客户端服务器通信必须使用Socket对象中获取到的网络流对象,不能使用自己定义的流对象
2. 必须服务器端先启动,否则抛出异常
4. ServerSocket:
a. 构造方法:
ServerSocket(int port);//在指定端口开启服务器端
b. 重要成员方法:
Socket accept();//获取请求的客户端对象
c. 使用方法:
1. 传入指定端口号,创建服务器端对象
2. 使用服务器端对象的accept成员方法获取请求的客户端Socket对象
3. 使用获取到的客户端Socket对象的getInputStream获取输入流对象
4. 使用InputStream对象的read方法读取客户端发送的字节流数据
5. 使用获取到的客户端Socket对象的getOutputStream获取输出流对象
6. 使用OutputStream对象的write方法向客户端发送字节流数据
7. 关闭获取到的Socket对象
8. 关闭服务器对象ServerSocket
TCP文件上传与下载
1. 原理:客户端读取本地的文件,把文件上传到服务器,服务器将上传的文件保存到服务器的硬盘上
2. 使用步骤:
a. 客户端使用<本地字节输入流>,读取要上传的文件
b. 客户端使用(网络字节输出流),将读取的文件上传到服务器
c. 服务器使用(网络字节输入流),读取客户端上传的文件
d. 服务器端使用<本地字节输出流>,将读取到的文件保存到服务器硬盘上
e. 服务器端使用(网络字节输出流),给客户端发送上传完毕消息
f. 客户端使用(网络字节输出流),读取服务器端写回的数据
g. 释放资源
3. 注意事项:
由于上传文件的while循环条件while((len = fis.read(bytes))!=-1)
因此,无法发送结束标识,使得服务器和客户端无法停止
解决方案:
当客户端上传完毕后,需要调用成员方法shutdownOutput
用于禁用此套接字
对于TCP套接字,任何之前写入的数据都将被发送,且跟一个TCP正常连接终止序列
4. 服务器端优化:多线程
a. 将保存文件的方法写到线程run方法中
b. 每次来一个客户端请求,开启一个线程
c. 由于run方法没有声明抛出异常,所以子类实现同样不能抛出IOException,需要使用try/catch