运行方式
项目目录:
先运行服务端TCPserver.java再运行客户端TCPclient.java(用户名:zs 密码:123)。
D:\client文件夹作为客户端文件系统(其中D:\client\download\中存放从服务端下载下来的文件; D:\client\中存放要说上传给服务器的文件),D:\server文件夹作为服务端文件系统(其中D:\server\upload\存放从客户端上传的文件)
TCPclient.java:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/*
实现步骤:
1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传到服务器
6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
7.使用网络字节输入流InputStream对象中的方法read读取服务回写的数据
8.释放资源(FileInputStream,Socket)
*/
public class TCPClient {
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
boolean flag = true;
//
// 用户登录
login(in);
while (flag) {
System.out.println("请输入对应序号选择功能:");
System.out.println("0、退出系统");
System.out.println("1、从服务中获取文件的元数据列表");
System.out.println("2、上传文件");
System.out.println("3、下载文件");
System.out.println("4、检查磁盘空间");
String key = in.nextLine();
Socket socket = new Socket("127.0.0.1", 8686);
DataOutputStream dos = new DataOutputStream(
socket.getOutputStream());
dos.writeUTF(key);
dos.close();
socket.close();
switch (key) {
case "1":
// 从服务中获取文件的元数据
getDB();
break;
case "2":
// 上传文件
sendFile(in);
break;
case "3":
// 下载文件
receiveFile(in);
break;
case "4":
space();
break;
case "0":
flag = false;
break;
default:
System.out.println("输入无效,请重新输入");
break;
}
}
// socket.close();
in.close();
}
public static void sendFile(Scanner in) throws IOException {
String fileName = null;
String flag = "Y";
FileInputStream fis = null;
Socket socket = null;
while (flag.equals("Y")) {
System.out.println("请输入要上传的文件名:");
fileName = in.nextLine();
File file = new File("d:\\client\\" + fileName);
// 1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
fis = new FileInputStream(file);
// 2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
socket = new Socket("127.0.0.1", 8686);
// 3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
// 文件名、大小等属性
dos.writeUTF(file.getName());
dos.flush();
// dos.writeLong(file.length());
// 4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes)) != -1) {
// 5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传到服务器
os.write(bytes, 0, len);
}
/*
* 解决:上传完文件,给服务器写一个结束标记 void shutdownOutput() 禁用此套接字的输出流。 对于 TCP
* 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。
*/
socket.shutdownOutput();
// }
System.out.println("上传成功");
System.out.println("是否继续上传:Y/N");
flag = in.nextLine();
sendmess(flag);
// 8.释放资源(FileInputStream,Socket)
// is.close();
dos.close();
os.close();
socket.close();
fis.close();
}
}
public static void receiveFile(Scanner in) throws IOException {
String fileName = null;
String flag = "Y";
FileOutputStream fos = null;
Socket socket = null;
InputStream is = null;
DataOutputStream dos = null;
while (flag.equals("Y")) {
System.out.println("请输入要下载的文件名:");
fileName = in.nextLine();
File dir = new File("d:\\client\\download");
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir + "\\" + fileName);
if (!file.exists()) {
file.createNewFile();
}
// 1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
fos = new FileOutputStream(file);
// 2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
socket = new Socket("127.0.0.1", 8686);
// 3.使用Socket中的方法getInputStream,获取网络字节输入流getInputStream对象
is = socket.getInputStream();
// 给服务器发送要下载的文件名
dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(fileName);
dos.flush();
int len = 0;
byte[] bytes = new byte[1024];
while ((len = is.read(bytes)) != -1) {
// 7.使用本地字节输入流FileIntputStream对象中的方法read,把读取到的文件保存到本地的硬盘上
fos.write(bytes, 0, len);
}
System.out.println("下载成功!");
System.out.println("是否继续下载:Y/N");
flag = in.nextLine();
sendmess(flag);
// 8.释放资源(FileInputStream,Socket)
dos.close();
is.close();
socket.close();
fos.close();
}
}
public static void login(Scanner in) throws IOException {
int tag = 0;
Socket socket = new Socket("127.0.0.1", 8686);
DataOutputStream dos = null;
DataInputStream dis = null;
while (tag == 0) {
System.out.println("请输入用户名:");
String uname = in.nextLine();
System.out.println("请输入密码:");
String pwd = in.nextLine();
dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(uname);
dos.flush();
dos.writeUTF(pwd);
dos.flush();
dis = new DataInputStream(socket.getInputStream());
tag = dis.readInt();
if (tag == 1) {
System.out.println("登录成功!");
} else {
System.out.println("用户名或密码错误!请重新输入");
}
}
dis.close();
dos.close();
socket.close();
}
public static void getDB() throws IOException {
Socket socket = new Socket("127.0.0.1", 8686);
DataInputStream dis = new DataInputStream(socket.getInputStream());
int len = dis.readInt();
for (int i = 0; i < len; i++) {
System.out.println(dis.readUTF());
}
dis.close();
socket.close();
}
public static void space() throws IOException {
File file = new File("D:");
long totalSpace = file.getTotalSpace();
long freeSpace = file.getFreeSpace();
System.out.println("本地:");
System.out.println("总空间大小 : " + totalSpace / 1024 / 1024 / 1024 + "G");
System.out.println("剩余空间大小 : " + freeSpace / 1024 / 1024 / 1024 + "G\n");
Socket socket = new Socket("127.0.0.1", 8686);
DataInputStream dis = new DataInputStream(socket.getInputStream());
long StotalSpace = dis.readLong();
long SfreeSpace = dis.readLong();
System.out.println("服务器:");
System.out.println("总空间大小 : " + StotalSpace / 1024 / 1024 / 1024 + "G");
System.out.println("剩余空间大小 : " + SfreeSpace / 1024 / 1024 / 1024 + "G\n");
dis.close();
socket.close();
}
public static void sendmess(String str) throws IOException{
Socket socket = new Socket("127.0.0.1", 8686);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(str);
dos.close();
socket.close();
}
}
TCPserver.java:
import java.text.SimpleDateFormat;
import java.util.List;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import java.util.Scanner;
import java.io.FileWriter;
/*
文件上传案例服务器端:读取客户端上传的文件,保存到服务器的硬盘,给客户端回写"上传成功"
明确:
数据源:客户端上传的文件
目的地:服务器的硬盘 d:\\upload\\1.jpg
实现步骤:
1.创建一个服务器ServerSocket对象,和系统要指定的端口号
2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象
3.使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象
4.判断d:\\upload文件夹是否存在,不存在则创建
5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地
6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上
8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象
9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写"上传成功"
10.释放资源(FileOutputStream,Socket,ServerSocket)
*/
public class TCPServer {
private static List<String> DB = new ArrayList<String>();
public static void main(String[] args) throws IOException {
// 1.创建一个服务器ServerSocket对象,和系统要指定的端口号
ServerSocket server = new ServerSocket(8686);
//从DB.txt文件中那数据给DB
initDB(DB);
String flag = "Y";
while(true){
//验证登录
check(server);
while(flag.equals("Y")){
Socket socket = server.accept();
DataInputStream dis = new DataInputStream(
socket.getInputStream());
String key = dis.readUTF();
dis.close();
socket.close();
switch (key.charAt(0)) {
case '1':
//发送元数据给客户端
sendDB(server);
break;
case '2':
//上传文件
takeFile(server);
break;
case '3':
//下载文件
sendFile(server);
break;
case '4':
//发送磁盘空间
sendspace(server);
break;
case '0':
flag = "N";
break;
default:
break;
}
}
}
//把新的DB重新存入DB.txt
// saveDB(DB);
// socket.close();
// server.close();
}
public static void takeFile(ServerSocket server) throws IOException {
// 2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象
/*
* 让服务器一直处于监听状态(死循环accept方法) 有一个客户端上传文件,就保存一个文件
*/
String flag = "Y";
while (flag.equals("Y")) {
Socket socket = server.accept();
/*
* 使用多线程技术,提高程序的效率 有一个客户端上传文件,就开启一个线程,完成文件的上传(取消使用)
*/
// 完成文件的上传
try {
// 3.使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象
InputStream is = socket.getInputStream();
DataInputStream dis = new DataInputStream(
socket.getInputStream());
// 文件名(和长度)
String fileName = dis.readUTF();
// long fileLength = dis.readLong();
// 4.判断d:\\upload文件夹是否存在,不存在则创建
File file = new File("d:\\server\\upload");
if (!file.exists()) {
file.mkdirs();
}
// 5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地
FileOutputStream fos = new FileOutputStream(file + "\\" + fileName);
// 6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
int len = 0;
// StringBuilder sb = new StringBuilder();
byte[] bytes = new byte[1024];
while ((len = is.read(bytes)) != -1) {
// 7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上
fos.write(bytes, 0, len);
// 文件元数据
File f = new File(file + "\\" + fileName);
Date dd = new Date();
// 格式化
SimpleDateFormat sim = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
String Udate = sim.format(dd);
String size = "" + f.length() + "bytes";
DB.add(fileName + "\t" + size + "\t" + Udate);
flag = getmess(server);
// socket1.close();
//更新数据库文件
saveDB(DB);
// 10.释放资源(FileOutputStream,Socket,ServerSocket)
fos.close();
dis.close();
is.close();
// socket.close();
// System.out.println(DB);
} catch (IOException e) {
System.out.println(e);
}
}
}
public static void sendFile(ServerSocket server) throws IOException {
String flag = "Y";
while(flag.equals("Y")){
/*
* 使用多线程技术,提高程序的效率 有一个客户端下载文件,就开启一个线程,完成文件的下载(取消使用)
*/
Socket socket = server.accept();
try{
//读取下载的文件名
DataInputStream dis = new DataInputStream(
socket.getInputStream());
String fileName = dis.readUTF();
File file = new File("d:\\server\\upload\\"+fileName);
//1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
FileInputStream fis = new FileInputStream(file);
//3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
//4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
int len = 0;
byte[] bytes = new byte[1024];
while((len = fis.read(bytes))!=-1){
//5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件发送给客户端
os.write(bytes,0,len);
}
/*
解决:上传完文件,给服务器写一个结束标记
void shutdownOutput() 禁用此套接字的输出流。
对于 TCP 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。
*/
socket.shutdownOutput();
flag = getmess(server);
//8.释放资源(FileInputStream,Socket)
dos.close();
os.close();
fis.close();
dis.close();
// socket.close();
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void check(ServerSocket server) throws IOException{
Socket socket = server.accept();
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
DataInputStream dis = new DataInputStream(
socket.getInputStream());
String uname = null;
String pwd = null;
int tag = 0;
while(tag==0){
uname = dis.readUTF();
pwd = dis.readUTF();
if(uname.equals("zs")&&pwd.equals("123")){
dos.writeInt(1);
tag = 1;
}else{
dos.writeInt(0);
tag = 0;
}
}
dis.close();
dos.close();
socket.close();
}
public static void sendDB(ServerSocket server) throws IOException{
Socket socket = server.accept();
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
int len = DB.size();
dos.writeInt(len);
for(int i=0;i<len;i++){
dos.writeUTF(DB.get(i));
}
dos.close();
socket.close();
}
public static void saveDB(List<String> DB ) throws IOException {
FileWriter fw = new FileWriter("D:\\server\\DB\\DB.txt");
int len = DB.size();
for(int i=0;i<len;i++){
fw.write(DB.get(i));
fw.write("\r\n");
}
fw.close();
}
public static void initDB(List<String> DB ) throws IOException{
File file = new File("D:\\server\\DB\\DB.txt");
if(file.length()==0){
return;
}
FileInputStream fis = new FileInputStream("D:\\server\\DB\\DB.txt");// FileInputStream
// 从文件系统中的某个文件中获取字节
InputStreamReader isr = new InputStreamReader(fis);// InputStreamReader 是字节流通向字符流的桥梁,
BufferedReader br = new BufferedReader(isr);// 从字符输入流中读取文件中的内容,封装了一个new InputStreamReader的对象
String str = null;
while ((str = br.readLine()) != null) {
DB.add(str);
// System.out.println(str);
}
br.close();
}
public static void sendspace(ServerSocket server) throws IOException{
File file = new File("D:");
long totalSpace = file.getTotalSpace();
long freeSpace = file.getFreeSpace();
Socket socket = server.accept();
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeLong(totalSpace);
dos.writeLong(freeSpace);
dos.close();
socket.close();
}
public static String getmess(ServerSocket server) throws IOException{
Socket socket = server.accept();
DataInputStream dis = new DataInputStream(socket.getInputStream());
String mess = dis.readUTF();
dis.close();
socket.close();
return mess;
}
}