目录
实现了将超星学习通项目的客户端与服务端分离
客户端方面
登录
- User对象序列化传输到服务端,服务端据此判断账号密码是否正确
- 接收到服务端传来的Message对象,Message对象包含是否登录成功的信息
- 若登录成功,就创建一个线程用于和服务端保持通信
- 若登录失败,就关闭与服务器的连接
public class UserClientService {
User user;
Socket socket;
public boolean UserCheck(String id,String pwd){
boolean re=false;
user =new User(id,pwd);
try {
socket=new Socket("127.0.0.1",10086);
//将用户发送到服务端
ObjectOutputStream oos=new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(user);
//从服务器接收消息,是否登录成功
ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
Message ms=(Message) ois.readObject();
if(ms.getState()== StateType.Longin_Success){
System.out.println("登录成功");
//登录成功,创建与服务器保持通信的线程
ClientConnectServer ccs=new ClientConnectServer(socket);
ccs.start();
//将线程放入集合中管理
ControlCSConnectionThread.addCSThread(user.getId(), ccs);
re=true;
}else{
//无法启动线程
//但socket是打开的
System.out.println("登陆失败");
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return re;
}
}
将这个类组合在控件Button Login(登录按钮)的control类中,在点击按钮时,运行UserCheck方法。
@FXML
public void toLogin(ActionEvent event){
if(zh.getText().equals("")||mm.getText().equals(""))
{
error.setText("请输入账号或密码");
}
else{
if(userClientService.UserCheck(zh.getText(), mm.getText())){
error.setText("密码正确");
System.out.println("即将跳转至超星主界面");
return;
}
error.setText("账号或密码错误");
}
}
//error为提示label
通信线程
public class ClientConnectServer extends Thread{
private Socket socket;
public ClientConnectServer(Socket socket){
this.socket=socket;
}
@Override
public void run(){
//需要一直保持通信
while(true){
//一直等待从服务器发送过来的消息
System.out.println("等待服务器响应");
try {
ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
//服务器没有发送时,阻塞
Message ms=(Message) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public Socket getSocket() {
return socket;
}
}
服务端方面
登录
- 监听客户端连接
- 接收从客户端传来的User对象,与数据库中的相关表对比
- 发送对比结果Message对象
- 登录成功,创建一个线程与客户端保持通信
- 失败就关闭与该服务器的连接
- 循环监听
public class Server {
ServerSocket serverSocket=null;
public Server(){
try {
serverSocket=new ServerSocket(10086);
System.out.println("服务器正在监听10086端口");
while(true){
Socket socket=serverSocket.accept();
ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
User user=(User) ois.readObject();
Message ms=new Message();
ObjectOutputStream oos=new ObjectOutputStream(socket.getOutputStream());
//从数据库中获取密码
if(user.getPwd().equals(PwdFromBase.pwd(user.getId()))){
ms.setState(StateType.Longin_Success);
//向客户端发送密码正确,登录成功的xx
oos.writeObject(ms);
//启动服务端与客户端保持通信的线程
ServerConnectionClient scc=new ServerConnectionClient(socket,user.getId());
scc.start();
//将线程放入集合
ControlSCConnectionThread.addSCThread(user.getId(),scc);
}else{
ms.setState(StateType.Login_Fail);
oos.writeObject(ms);
socket.close();
}
}
} catch (Exception e) {
System.out.println("服务器监听出错");
e.printStackTrace();
}finally {
try {
serverSocket.close();
} catch (Exception e) {
System.out.println("服务器关闭异常");
}
}
}
}
通信线程
public class ServerConnectionClient extends Thread {
private Socket socket;
private String userid;
public ServerConnectionClient(Socket socket,String id){
this.socket=socket;
userid=id;
}
@Override
public void run(){
while(true){
System.out.println("服务端接受客户端的消息");
try {
ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
Message ms=(Message) ois.readObject();
} catch (Exception e) {
System.out.println("服务端接收客户端消息出错");
}
}
}
}
连接数据库
public class DataBaseConnect {
private static String url="jdbc:mysql:///superstar?&uesServerPrepStmts=true";
private static String username="root";
private static String password="111111";
//获取数据库连接
private static Connection conn;
public static Connection getConn() {
try {
conn = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
System.out.println("数据库连接出现问题");
}
return conn;
}
}
所有线程共用一个连接