package 服务器端相关操作;
import java.io.Serializable;
/*
* 创建存储需要传输信息的对象,方便客户端向服务器端传送数据
*/
public class ClientToServerInfo implements Serializable{
String sign;
String name;
String password_OR_path;
//重写构造函数
public ClientToServerInfo(String sign,String name,String password_OR_path){
this.sign=sign;
this.name=name;
this.password_OR_path=password_OR_path;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getName() {
return name;
}
public void setName(String Name) {
this.name = name;
}
public String getPassword_OR_path() {
return password_OR_path;
}
public void setPassword_OR_path(String password_OR_path) {
this.password_OR_path = password_OR_path;
}
@Override
public String toString() {
return "客户端说: [sign=" + sign + ", name=" + name + ", password_OR_path=" +password_OR_path + "]";
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 服务器端主程序操作
*/
public class Server {
public static void main(String[] args) {
try {
//1.创建服务器端的ServerSocket,指定伴随的端口号
ServerSocket serversocket=new ServerSocket(8880);
System.out.println("****服务器端即将启动,等待客户端*****");// 提示服务器开启
Socket socket=null;
while(true){
//2.调用accept()方法开始监听,等待客户端连接
socket=serversocket.accept();
//调用线程
ServerThread st=new ServerThread(socket);
st.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.sql.SQLException;
import Server_To_Client_Response.Add_File_Response;
import Server_To_Client_Response.Add_User_Response;
import Server_To_Client_Response.Select_User_Response;
public class ServerThread extends Thread {
//创建与本线程相关的socket
Socket socket=null;
ObjectInputStream ois=null;
//重写构造函数
public ServerThread(Socket socket){
this.socket=socket;
}
//线程操作 获取输出流,响应客户端的请求
public void run(){
try {
//3.获取输入流,并读取客户端信息
ois=new ObjectInputStream(socket.getInputStream());
/*
* 读取接收到的对象信息
*/
while( ois.available()!=-1){
ClientToServerInfo ctsi =(ClientToServerInfo)ois.readObject();
System.out.println(ctsi.toString());//打印客户端传到服务器的数据(对象)
/*
* 需要客户端传入的对象数据进行分析,根据传入的sign标志值进行相应的操作
* sign="1"完成注册会员操作,链接数据库,向数据库中user表添加记录
* sign="2"完成会员登录操作,连接数据库,在数据库中user表查询记录
* sign="3"完成文件上传操作,连接数据库,向数据库中file表添加记录
*/
//System.out.println(ctsi.sign);
if(ctsi.sign.equals("1")){
//调用 Add_User_Response类的构造方法对客户端传入的信息进行详细的响应
Add_User_Response aur=new Add_User_Response(socket, ctsi.name,ctsi.password_OR_path);
//System.out.println("运行完Add_User_Response类");
break;
}
if(ctsi.sign.equals("2")){
//调用 Select_User_Response类的构造方法对客户端传入的信息进行详细的响应
Select_User_Response sur=new Select_User_Response(socket, ctsi.name,ctsi.password_OR_path);
//System.out.println("运行完 Select_User_Response类");
break;
}
if(ctsi.sign.equals("3")){
//调用 Add_File_Response类的构造方法对客户端传入的信息进行详细的响应
Add_File_Response afr=new Add_File_Response(socket, ctsi.name,ctsi.password_OR_path);
// System.out.println("运行完 Add_File_Response类");
break;
}
}
//5.关闭资源
ois.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
1 package 客户端相关操作;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.InputStreamReader;
7 import java.io.ObjectOutputStream;
8 import java.io.OutputStream;
9 import java.io.PrintWriter;
10 import java.net.Socket;
11 import java.net.UnknownHostException;
12 import java.util.Scanner;
13
14 import org.eclipse.persistence.oxm.record.OutputStreamRecord;
15
16 import 服务器端相关操作.ClientToServerInfo;
17
18 public class Client {
19
20 public static void main(String[] args) throws UnknownHostException, IOException {
21 String []data=new String[3];
22 int sum=0;//用来记录客户端第几次传值到服务器端
23 /*
24 * 客户端界面的提示语句
25 */
26 ClientTips ctps=new ClientTips();
27 Scanner sc=new Scanner(System.in);
28 int n;
29
30 /*
31 * 客户端实现与服务器端交互
32 */
33
34 try {
35 while(true){//使得客户端始终处于程序运行当中
36 //1.创建客户端socket,指定服务器和端口号
37 Socket socket=new Socket("localhost", 8880);
38 OutputStream os=null;
39 InputStream is=null;
40 InputStreamReader isr=null;
41 BufferedReader br=null;
42 ClientToServerInfo ctsi=null;
43 ObjectOutputStream oos=null;
44 while(true){//通过循环让客户端完成注册、登录 和上传信息的客户界面操作
45 n=sc.nextInt();
46 /*
47 * data用于接收tipchoose返回的字符串数组
48 * 如果传入的值为1时返回的为三个非空字符串,分别为“1”和用户名和密码
49 * 如果传入的值为2是返回的为两个非空字符串,分别是“2”和用户名和密码
50 * 如果传入的值为3是返回的两个字符串,分别是“3”和data[0]=null,data[1]=文件路径
51 */
52 data=ctps.tipChoose(n);
53 if(data[0]!=null&&data[1]!=null){
54 //如果界面输入值合理,则跳出一层循环
55 break;
56 }
57 }
58
59
60 //2.获取输出流,向服务器端发送信息
61 os=socket.getOutputStream();//字节输出流
62
63 /*
64 *这里要判断是不是第一次写文件,若是则写入头部,否则不写入。
65 */
66 //if(sum==0){
67 oos=new ObjectOutputStream(os);
68 //}
69 /*else{
70 System.out.println(sum);
71 oos=new MyObjectOutputStream(os);
72 }*/
73
74
75 //将需要传送的信息封装成对象
76 ctsi=new ClientToServerInfo(data[0],data[1],data[2]);
77
78 oos.writeObject(ctsi);
79 oos.writeObject(null);//objectoutputstream写入结束的标志
80 oos.flush();
81 sum++;
82 //socket.shutdownOutput();//关闭输出流
83
84 //3.读取服务器端发送的信息
85 is=socket.getInputStream();
86 isr=new InputStreamReader(is);
87 br=new BufferedReader(isr);
88 String info=null;
89 if((info=br.readLine())!=null){
90 System.out.println("我是客户端,服务器说:"+info);
91 }
92 //用来区分不同次的客户端发送和服务器响应的命令
93 System.out.println("**************************");
94 //关闭输入输出流(关闭资源)
95 br.close();
96 isr.close();
97 is.close();
98 oos.close();
99 os.close();
100 socket.close();
101
102 }
103 } catch (IOException e) {
104 // TODO Auto-generated catch block
105 e.printStackTrace();
106 }
107 }
108 }
109
110
111 import java.util.Scanner;
112
113 public class ClientTips {
114 static boolean flag=false;
115 static String a;
116 public ClientTips(){
117 //打印客户端界面
118 System.out.println("*********************************");
119 System.out.println("注册信息:1");
120 System.out.println("登陆账号:2");
121 System.out.println("上传文件(只有在登陆之后才能传文件!):3");
122 System.out.println("*********************************");
123 }
124 public String[] tipChoose(int n){
125 String[] userinfo=new String[3];
126 String b,c,e;
127 Scanner sc=new Scanner(System.in);
128
129 /*
130 * 注册时的提示操作
131 */
132 if(n==1){
133 System.out.print("请输入要注册的账号名:");
134 a=sc.nextLine();
135 System.out.print("请输入密码:");
136 b=sc.nextLine();
137 System.out.print("请确认密码:");
138 c=sc.nextLine();
139 if(!c.equals(b)){//这里不能用c!=b判断,c!=b不仅对比了字符串,还对比了存储地址
140 System.out.println("密码不一致!注册失败,需要重新注册请输入:1");
141 //如果注册失败,userinfo返回的为空数组
142 userinfo[0]=null;
143 userinfo[1]=null;
144 userinfo[2]=null;
145 }
146 else{
147 userinfo[0]="1";
148 userinfo[1]=a;
149 userinfo[2]=b;
150 }
151 }
152 /*
153 * 登陆时提示信息操作
154 */
155 if(n==2){
156 System.out.print("请输入要登陆的账号名:");
157 a=sc.nextLine();
158 System.out.print("请输入密码:");
159 b=sc.nextLine();
160 userinfo[0]="2";
161 userinfo[1]=a;
162 userinfo[2]=b;
163 flag=true;
164
165 }
166
167 /*
168 * 传送文件相关文件
169 */
170 if(n==3){
171 if(flag!=true){
172 System.out.println("请先登录账号!请输入2");
173 //如果没有登陆操作,输入3时先返回空数组
174 userinfo[0]=null;
175 userinfo[1]=null;
176 userinfo[2]=null;
177 }
178 else{
179 System.out.println("请输入文件的路径:");
180 e=sc.nextLine();
181 userinfo[0]="3";
182 userinfo[1]=a;
183 userinfo[2]=e;
184 }
185 }
186 return userinfo;
187 }
188 }
189
190
191 import java.io.Serializable;
192
193 /*
194 * 创建存储需要传输信息的对象,方便客户端向服务器端传送数据
195 */
196 public class ClientToServerInfo implements Serializable{
197 String sign;
198 String name;
199 String password_OR_path;
200 //重写构造函数
201 public ClientToServerInfo(String sign,String name,String password_OR_path){
202 this.sign=sign;
203 this.name=name;
204 this.password_OR_path=password_OR_path;
205 }
206
207 public String getSign() {
208 return sign;
209 }
210 public void setSign(String sign) {
211 this.sign = sign;
212 }
213 public String getName() {
214 return name;
215 }
216 public void setName(String Name) {
217 this.name = name;
218 }
219 public String getPassword_OR_path() {
220 return password_OR_path;
221 }
222 public void setPassword_OR_path(String password_OR_path) {
223 this.password_OR_path = password_OR_path;
224 }
225 @Override
226 public String toString() {
227 return "客户端说: [sign=" + sign + ", name=" + name + ", password_OR_path=" +password_OR_path + "]";
228 }
229
230 }
231
232
233 import java.io.IOException;
234 import java.io.ObjectOutputStream;
235 import java.io.OutputStream;
236 /*
237 * 在一个文件都有一个文件的头部和文件体。由于对多次使用FileOutputStream(文件名,true)
238 * 构建的ObjectOutputStream对象向同一个文件写数据,在每次些数据的时候他都会向这个文件末
239 * 尾先写入header在写入你要写的对象数据,在读取的时候遇到这个在文件体中的header就会报错。
240 * 导致读出时,出现streamcorrput异常。(解决办法:所以这里要判断是不是第一次写文件,若是
241 * 则写入头部,否则不写入)
242 */
243 public class MyObjectOutputStream extends ObjectOutputStream {
244
245 protected MyObjectOutputStream() throws IOException, SecurityException {
246 super();
247 }
248
249
250 public MyObjectOutputStream(OutputStream out) throws IOException {
251 super(out);
252 }
253 @Override
254
255 protected void writeStreamHeader() throws IOException {
256 return;
257 }
258 }
1 package Database;
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.SQLException;
6
7 public class DBUtil {
8
9 private static final String URL="jdbc:mysql://127.0.0.1:3306/imooc?useUnicode=true&characterEncoding=utf-8";
10 private static final String USER="root";
11 private static final String PASSWORD="tiger";
12
13 private static Connection conn=null;
14
15 static {
16 try {
17 //1.加载驱动程序
18 Class.forName("com.mysql.jdbc.Driver");
19 //2.获得数据库的连接
20 conn=DriverManager.getConnection(URL, USER, PASSWORD);
21 } catch (ClassNotFoundException e) {
22 e.printStackTrace();
23 } catch (SQLException e) {
24 e.printStackTrace();
25 }
26 }
27 //将获得的数据库与java的链接返回(返回的类型为Connection)
28 public static Connection getConnection(){
29 return conn;
30 }
31
32 }
33
34 /*
35 * 服务器端链接数据库,并向数据库表user添加数据
36 * 添加成功返回true,否则返回false
37 */
38 import java.sql.Connection;
39 import java.sql.PreparedStatement;
40 import java.sql.SQLException;
41
42 public class Database_Add_User {
43 boolean flag=false;
44 //
45 public boolean Database_Add_User_run(String name,String password_OR_path) throws SQLException{
46 //获取mysql链接
47 System.out.println("开始运行Database_Add_User类");
48 Connection conn=DBUtil.getConnection();
49 String sql=""+"insert into user"+"(user_name,user_password)"
50 +"values("+"?,?)";
51 //加载sql语句到执行程序中(并不进行执行)
52 PreparedStatement ptmt=conn.prepareStatement(sql);
53 ptmt.setString(1, name);
54 ptmt.setString(2, password_OR_path);
55 flag=ptmt.execute();
56 return flag;
57 }
58 }
59
60 /*
61 * 用于用户登录时,将账号和密码传递到数据库,
62 * 若登录名不存在file表中(即未注册)返回2
63 * 若登录名存在file表中,密码输入正确返回1
64 * 若登录名存在file表中,密码输入错误返回3
65 */
66 import java.sql.Connection;
67 import java.sql.PreparedStatement;
68 import java.sql.ResultSet;
69 import java.sql.SQLException;
70
71 public class Database_Select_User {
72
73
74 public int Database_Select_User_run(String name,String password_OR_path) throws SQLException{
75 //获取mysql链接
76 Connection conn=DBUtil.getConnection();
77 String sql1=""+"select * from user where user_name like ?";
78 PreparedStatement ptmt=conn.prepareStatement(sql1.toString());
79 ptmt.setString(1, "%"+name+"%");
80 ResultSet rs=ptmt.executeQuery();
81 while(rs.next()){
82 //判断密码是否正确,正确返回1
83 if(rs.getString("user_password").equals(password_OR_path)){
84 return 1;
85 }
86 //判断密码错误返回2
87 else
88 return 3;
89 }
90 //用户名不存在返回2
91 return 2;
92
93 }
94
95 }
96
97 /*
98 * 服务器端链接数据库,并向数据库表file添加数据
99 * 添加成功返回false,否则返回true
100 */
101
102 import java.io.File;
103 import java.io.FileInputStream;
104 import java.io.FileNotFoundException;
105 import java.io.InputStream;
106 import java.sql.Connection;
107 import java.sql.PreparedStatement;
108 import java.sql.SQLException;
109
110 public class Database_Add_File {
111 boolean flag=false;
112 //
113 public boolean Database_Add_File_run(String name,String password_OR_path) throws SQLException, FileNotFoundException{
114 //获取mysql链接
115 File files = new File(password_OR_path);
116 Connection conn=DBUtil.getConnection();
117 String sql=""+"insert into file"+"(user_name,path)"
118 +"values("+"?,?)";
119 //加载sql语句到执行程序中(并不进行执行)
120 PreparedStatement ptmt=conn.prepareStatement(sql);
121 ptmt.setString(1, name);
122 //ptmt.setString(2, password_OR_path);
123 FileInputStream fis = new FileInputStream(files);
124 ptmt.setBinaryStream(2, (InputStream) fis, (int) (files.length()));
125 flag=ptmt.execute();
126 return flag;
127 }
128 }
1 package Server_To_Client_Response;
2 /*
3 * 判断客户端传入到服务器端的注册会员数据,提交到数据库中,
4 * 是否在数据库中添加成功,并完成对客户端的响应,成功返回注册成功,
5 * 反之提示其重新注册
6 */
7 import java.io.IOException;
8 import java.io.OutputStream;
9 import java.io.PrintWriter;
10 import java.net.Socket;
11 import java.sql.SQLException;
12
13 import Database.Database_Add_User;
14
15 public class Add_User_Response {
16 Socket socket=null;
17 boolean flag;
18 public Add_User_Response(Socket socket,String name,
19 String password_OR_path ) throws SQLException{
20
21 try {
22 System.out.println("运行Add_User_Response类");
23 //将已创建的socket对象加载进来
24
25 this.socket=socket;
26 OutputStream os=socket.getOutputStream();
27 PrintWriter pw=new PrintWriter(os);
28 /*
29 * 创建和数据库的链接,完成向user表格中添加记录操作
30 * 添加成功返回false,否则返回true
31 */
32 Database_Add_User dau=new Database_Add_User();
33 flag=dau.Database_Add_User_run(name, password_OR_path);
34 //System.out.println("运行完Database_Add_User类");
35 /*
36 * 对插入数据后的返回值进行分析,并对客户端进行响应
37 */
38 if(!flag){
39 //获取输出流,响应客户端的请求
40 pw.write("您已经成功注册!");
41 pw.flush();
42
43 }
44 else{
45 pw.write("注册失败!");
46 pw.flush();
47
48 }
49 //关闭输入输出流(关闭资源)
50 pw.close();
51 os.close();
52 } catch (IOException e) {
53 // TODO Auto-generated catch block
54 e.printStackTrace();
55 }finally {
56
57 try {
58
59 socket.close();
60 } catch (IOException e) {
61 // TODO Auto-generated catch block
62 e.printStackTrace();
63 }
64 }
65
66 }
67 }
68
69
70 /*
71 * 判断客户端传入到服务器端的上传文件数据,提交到数据库中,
72 * 是否在数据库中添加成功,并完成对客户端的响应,成功返回上传成功,
73 * 反之提示其重新上传
74 */
75 import java.io.IOException;
76 import java.io.OutputStream;
77 import java.io.PrintWriter;
78 import java.net.Socket;
79 import java.sql.SQLException;
80
81 import Database.Database_Add_File;
82
83 public class Add_File_Response {
84 OutputStream os=null;
85 PrintWriter pw=null;
86 Socket socket=null;
87 boolean flag;
88 public Add_File_Response(Socket socket,String name,
89 String password_OR_path ) throws SQLException, IOException{
90 //将已创建的socket对象加载进来
91 this.socket=socket;
92 os=socket.getOutputStream();
93 pw=new PrintWriter(os);
94 /*
95 * 创建和数据库的链接,完成向file表格中添加记录操作
96 * 添加成功返回false,否则返回true
97 */
98
99 Database_Add_File dau=new Database_Add_File();
100 flag=dau.Database_Add_File_run(name, password_OR_path);
101
102 /*
103 * 对插入数据后的返回值进行分析,并对客户端进行响应
104 */
105 if(!flag){
106 //获取输出流,响应客户端的请求
107 pw.write("文件上传成功!");
108 pw.flush();
109 }
110 else{
111 pw.write("文件上传失败!请重新上传!");
112 pw.flush();
113 }
114 //关闭输入输出流(关闭资源)
115 pw.close();
116 os.close();
117 }
118 }
119
120
121 /*
122 * 判断客户端传入到服务器端的会员数据,提交到数据库中,
123 * 在数据库中查找,是否注册,密码是否正确,若账号名和密码都正确,登陆成功
124 * 并完成对客户端的响应。
125 */
126 import java.io.IOException;
127 import java.io.OutputStream;
128 import java.io.PrintWriter;
129 import java.net.Socket;
130 import java.sql.SQLException;
131
132 import Database.Database_Select_User;
133
134 public class Select_User_Response {
135 //输出流的初始化,为服务器对客户端的响应做准备
136 OutputStream os=null;
137 PrintWriter pw=null;
138 Socket socket=null;
139 int flag;
140 public Select_User_Response(Socket socket,String name,
141 String password_OR_path) throws IOException, SQLException{
142 this.socket=socket;
143 os=socket.getOutputStream();
144 pw=new PrintWriter(os);
145 /*
146 * 创建和数据库的链接,完成对user表格的查询操作(完成登陆)
147 * 若登录名不存在file表中(即未注册)返回2
148 * 若登录名存在file表中,密码输入正确返回1
149 * 若登录名存在file表中,密码输入错误返回3
150 */
151 Database_Select_User dsu=new Database_Select_User();
152 flag=dsu.Database_Select_User_run(name,password_OR_path);
153
154 /*
155 * 对查找返回的数据进行分析,并对客户端进行响应
156 */
157 if(flag==1){
158 pw.write("欢迎您,你已经完成登陆!请输入3");
159 pw.flush();
160 }
161 else if(flag==2){
162 pw.write("您还没进行注册,请先注册!");
163 pw.flush();
164 }
165 else{
166 pw.write("密码错误!请重新登陆!请输入2");
167 pw.flush();
168 }
169 //关闭输出输入流(关闭资源)
170 pw.close();
171 os.close();
172 }
173 }