1实现技术:io流,序列化和反序列化,socket,java的一些绘图工具,配置文件的读取,线程等。
2实现步骤:
1>我们要分别建立服务器端和客户端
2>我们首先编写客服端
<1>建立一个登录Login的类,用于用户登录页面,该类要继承JFrame(主要是绘图),并且实现ActionListener接口(用于接听鼠标事件);
public class Login extends JFrame implements ActionListener{
JLabel jbl1;
JPanel jp2;
JLabel jp2_jbl1, jp2_jbl2;
JTextField jp2_jtf;
JPasswordField jp2_jpf;
JPanel jp1;
JButton jp1_jb1;
public Login(){
jbl1=new JLabel();
//登录界面
jp1 = new JPanel();
jp1_jb1 = new JButton("登录");
jp1_jb1.addActionListener(this);
jp1.add(jp1_jb1);
//输入账号界面
jp2 = new JPanel(new GridLayout(2, 2));
jp2_jbl1 = new JLabel("用户名", JLabel.CENTER);
jp2_jbl2 = new JLabel("密码", JLabel.CENTER);
jp2_jtf = new JTextField();
jp2_jpf = new JPasswordField();
jp2.add(jp2_jbl1);
jp2.add(jp2_jtf);
jp2.add(jp2_jbl2);
jp2.add(jp2_jpf);
this.add(jp1, "South");
this.add(jp2, "Center");
this.add(jbl1, "North");
this.setSize(300, 200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
Login login=new Login();
}
@Override
public void actionPerformed(ActionEvent e){
}
}
<2>接下来获取用户输入的信息,并将信息封装到user类中,但是我们还没有user类,这里可以先创建一个user类
附录:user(实现Serializable接口,一般用于传输的对象都需实现该接口,主要用于标识)
public class User implements Serializable{
private static final long serialVersionUID = 1L;
//用户名称和用户密码
private String userId;
private String password;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
回到login中actionPerformed方法
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==jp1_jb1){
//获取用户输入的信息,并将信息封装到user类中
User user=new User();
user.setUserId(jp2_jtf.getText().trim());
user.setPassword(new String(jp2_jpf.getPassword()));
//通过checkUser检查user的信息是否正确
if(CheckUser.checkUser(user)){
//如果返回结果存在该用户,则创建文件上传下载页
}else{
JOptionPane.showMessageDialog(this, "用户名或密码错误");
}
}
}
<3>写到这里我们明显需要一个类来检测用户信息,我将这个类做成了一个工具类checkUser,检测方法是checkUser,
为了方便调用,我将这个方法做成静态方法,代码如下
public class CheckUser {
public static boolean checkUser(User user){
boolean flag=false;
SocketConnection conn=new SocketConnection();
if(conn.clientToService(user).getMessageType().equals(MessageType.message_login_success)){
flag=true;
}
return flag;
}
}
<4>这里我们需要建立另外一个类用于和服务器端进行连接SocketConnection,并将返回结果做一比较,这里你可能不太理解MessageType的作用,其实就是一个接口,其中的属性就是用于判断客户端和服务器端信息交流的类型;
这里附上MessageType类
public interface MessageType {
String message_login_success = "1";
String message_login_fail = "2";
String message_download = "3";
String message_upload = "4";
String message_filename="5";
}
<5>现在来实现SocketConnection类,Socket中添加属性分别是主机ip,和端口号
public class SocketConnection {
private Socket socket;
public Message clientToService(Object obj){
Message message=null;
try {
//序列化传送对象
socket=new Socket("localhost",3333);
ObjectOutputStream out=new ObjectOutputStream(socket.getOutputStream());
out.writeObject(obj);
//假设服务器端已经传回对象,应该反序列化对象,讲对象返回
ObjectInputStream in=new ObjectInputStream(socket.getInputStream());
message=(Message) in.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return message;
}
}
<6>这样,我们客户端login的方法基本写完,接下来编写服务器端的方法,服务器端我们先创建一个类serverHub,用于开启和关闭服务器的方法,
public class ServerHub extends JFrame implements ActionListener{
JPanel jp1;
JButton jb1, jb2;
JTextArea jta;
public ServerHub(){
jp1 = new JPanel();
jta = new JTextArea();
jb1 = new JButton("开启服务器");
jb2 = new JButton("关闭服务器");
jb1.addActionListener(this);
jb2.addActionListener(this);
jp1.add(jb1);
jp1.add(jb2);
jta.setSize(700, 700);
this.add(jp1, "North");
this.add(jta, "Center");
this.setDefaultCloseOperation(3);
this.setSize(800, 600);
this.setVisible(true);
}
public static void main(String[] args) {
ServerHub server=new ServerHub();
}
@Override
public void actionPerformed(ActionEvent e) {
Server server=new Server();
if(e.getSource()==jb1){
server.start();
}else if(e.getSource()==jb2){
server.destroy();
}
}
}
<7>接下来写Server类,这里将Server变成一个线程,在服务器端,我们也需要User类和Messag