实验目的
了解线程的基本概念;掌握线程的构造,调度,控制策略;掌握多线程互斥和同步处理方法。
实验内容
编写程序,将前面课程所编写的档案管理系统的服务器端改写为多线程方式,使得其能同时处理多个客户端的请求。
本次代码沿用第三次中的User.java、Administrator.java、Operator.java、Browser.java和Doc.java,第五次中的DataProcessing.java和第六次的LoginWindow.java、MenuWindow.java、UserWindow.java、UpDownloadWindow.java、WinMain.java和PasswordWindow.java
并和大部分了第六次的Client.java和Server.java代码一样
客户端
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
public class Client extends JFrame {
private static String user_role="";
private static JFrame Jframe;
private static ObjectOutputStream output;
private static ObjectInputStream input;
private String message = "";
private static String user_name="";
private static String user_password="";
private String chatServer;
private static Socket client;
private static int row;
private static int row2;
private static String[][] UserData;
private static String[][] DocData;
public Client( String host ){
super( "Client" );
}
public void runClient(){
try{
connectToServer();
getStreams();
try {
processConnection();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
catch ( EOFException eofException ) {
displayMessage( "Client terminated connection" );
}
catch ( IOException ioException ){
ioException.printStackTrace();
}
finally{
try {
closeConnection();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void connectToServer() throws IOException{
displayMessage( "Attempting connection" );
client = new Socket( InetAddress.getByName( chatServer ), 12345 );
displayMessage( "Connected to: " +
client.getInetAddress().getHostName() );
}
private void getStreams() throws IOException{
output = new ObjectOutputStream( client.getOutputStream() );
output.flush();
input = new ObjectInputStream( client.getInputStream() );
displayMessage( "Got I/O streams" );
}
private void processConnection() throws IOException, ClassNotFoundException{
do {
Message msg =(Message) input.readObject();
message=msg.get_message();
if(message.equals("LOGIN_TRUE")) {
user_role=msg.get_content().elementAt(0);
MenuWindow menuWindow=new MenuWindow();
menuWindow.showMenu();
Jframe.dispose();
}
else if(message.equals("LOGIN_FALSE")) {
JOptionPane.showMessageDialog(null, "账号或密码错误", "温馨提示", JOptionPane.ERROR_MESSAGE);
}
else if(message.equals("SELFCHANGE_TRUE")) {
JOptionPane.showMessageDialog(null, "修改成功", "温馨提示", JOptionPane.PLAIN_MESSAGE);
String password=msg.get_content().elementAt(0);
user_password=password;
System.out.println("SELFCHANGE_SUCCESS");
}
else if(message.equals("SELFCHANGE_FALSE")) {
JOptionPane.showMessageDialog(null, "修改失败", "温馨提示", JOptionPane.ERROR_MESSAGE);
}
else if(message.equals("displayedUser")) {
Vector<String> content=msg.get_content();
UserData=new String[50][3];
int i;
for(i=0;i<content.size()/3;i++) {
for(int j=0;j<3;j++) {
UserData[i][j]=content.elementAt(i*3+j);
}
}
row=i;
}
else if(message.equals("displayedDoc")) {
Vector<String> content=msg.get_content();
DocData=new String[50][5];
int i;
for(i=0;i<content.size()/5;i++) {
for(int j=0;j<5;j++) {
DocData[i][j]=content.elementAt(i*5+j);
}
}
row2=i;
}
else if(message.equals("DELETE_TRUE")) {
JOptionPane.showMessageDialog(null, "删除成功", "温馨提示", JOptionPane.PLAIN_MESSAGE);
Jframe.dispose();
output.writeObject(new Message("displayUser",null));
output.flush();
System.out.println("DELETE_SUCCESS");
}
else if(message.equals("DELETE_FALSE")) {
JOptionPane.showMessageDialog(null, "账号不存在", "温馨提示", JOptionPane.ERROR_MESSAGE);
}
else if(message.equals("ADD_TRUE")) {
JOptionPane.showMessageDialog(null, "添加成功", "温馨提示", JOptionPane.PLAIN_MESSAGE);
Jframe.dispose();
output.writeObject(new Message("displayUser",null));
output.flush();
System.out.println("ADD_SUCCESS");
}
else if(message.equals("ADD_FALSE")) {
JOptionPane.showMessageDialog(null, "添加失败", "温馨提示", JOptionPane.ERROR_MESSAGE);
}
else if(message.equals("UPDATE_TRUE")) {
JOptionPane.showMessageDialog(null, "修改成功", "温馨提示", JOptionPane.PLAIN_MESSAGE);
Jframe.dispose();
output.writeObject(new Message("displayUser",null));
output.flush();
System.out.println("UPDATE_SUCCESS");
}
else if(message.equals("UPDATE_FLASE")) {
JOptionPane.showMessageDialog(null, "修改失败", "温馨提示", JOptionPane.ERROR_MESSAGE);
}
else if(message.equals("UPLOAD_TRUE")) {
JOptionPane.showMessageDialog(null, "上传成功", "温馨提示", JOptionPane.PLAIN_MESSAGE);
System.out.println("UPLOAD_SUCCESS");
Jframe.dispose();
output.writeObject(new Message("displayDoc",null));
output.flush();
}
else if(message.equals("UPLOAD_FALSE")) {
JOptionPane.showMessageDialog(null, "上传失败", "温馨提示", JOptionPane.ERROR_MESSAGE);
}
else if(message.equals("SERVER>>> CLIENT_FILE_DOWN")) {
String filename=msg.get_content().elementAt(0).toString();
Long fileLength=Long.parseLong(msg.get_content().elementAt(1).toString());
FileOutputStream fos=new FileOutputStream(new File("C:\\downloadfile\\"+filename));
byte[] sendBytes=new byte[1024];
int transLen=0;
System.out.println("----开始下载文件<"+filename+">,文件大小为<"+fileLength+">----");
while(true) {
int read=0;
read=input.read(sendBytes);
if(read==-1) break;
transLen+=read;
System.out.println("下载文件进度"+100*transLen*1.0/fileLength+"%...");
fos.write(sendBytes,0,read);
fos.flush();
if(transLen>=fileLength) break;
}
fos.close();
System.out.println("----下载文件<"+filename+">成功----");
JOptionPane.showMessageDialog(null, "下载成功", "温馨提示", JOptionPane.PLAIN_MESSAGE);
}
} while ( !message.equals( "SERVER>>> TERMINATE" ) );
}
public static void closeConnection() throws IOException{
try{
output.close();
input.close();
client.close();
}
catch ( IOException e ) {
e.printStackTrace();
}
}
public static void prepareToClose() throws IOException {
String logout="CLIENT>>> CLIENT_LOGOUT";
output.writeObject(new Message(logout,null));
output.flush();
System.out.println(logout);
}
static void displayMessage( String messageToDisplay ){
SwingUtilities.invokeLater(
new Runnable()
{
public void run()
{
System.out.println(messageToDisplay);
}
}
);
}
synchronized public static void Login(String name,String password,JFrame frame) throws IOException {
user_name=name;
user_password=password;
Jframe=frame;
Vector<String> content=new Vector<String>();
content.addElement(name);
content.addElement(password);
output.writeObject(new Message("CLIENT>>> CLIENT_LOGIN",content));
output.flush();
System.out.println("CLIENT>>> CLIENT_LOGIN");
}
synchronized static void ChangeSelfInfo(String old_password,String new_password,String new_password2) throws IOException {
if(user_password.equals(old_password)) {
if(new_password.equals(new_password2)) {
String changeSelfInfo="CLIENT>>> CLIENT_SELF_MOD";
System.out.println("CLIENT>>> CLIENT_SELF_MOD");
Vector<String> content=new Vector<String>();
content.addElement(user_name);
content.addElement(new_password);
content.addElement(user_role);
output.writeObject(new Message(changeSelfInfo,content));
output.flush();
}
else {
JOptionPane.showMessageDialog(null, "两次输入的新密码不一致", "温馨提示", JOptionPane.ERROR_MESSAGE);
}
}
else {
JOptionPane.showMessageDialog(null, "密码错误", "温馨提示", JOptionPane.ERROR_MESSAGE);
}
}
static void Display_User() throws IOException {
output.writeObject(new Message("displayUser",null));
output.flush();
}
static void Display_Doc() throws IOException {
output.writeObject(new Message("displayDoc",null));
output.flush();
}
synchronized static void DelUser(String del_name, JFrame frame) throws IOException {
Jframe=frame;
if(del_name.equals(user_name)) {
JOptionPane.showMessageDialog(null, "无法删除", "温馨提示", JOptionPane.ERROR_MESSAGE);
}
else {
Vector<String> content=new Vector<String>();
content.addElement(del_name);
output.writeObject(new Message("USER_DELETE",content));
output.flush();
System.out.println("CLIENT>>> "+del_name+ " USER_DELETE");
}
}
synchronized static void UpdateUser(String name,String password,String role,JFrame frame) throws IOException {
Jframe=frame;
Vector<String> content=new Vector<String>();
content.addElement(name);
content.addElement(password);
content.addElement(role);
output.writeObject(new Message("USER_UPDATE",content));
output.flush();
System.out.println("CLIENT>>> "+name+ "USER_UPDATE");
}
synchronized static void AddUser(String name, String password,String role,JFrame frame) throws IOException {
Jframe=frame;
Vector<String> content=new Vector<String>();
content.addElement(name);
content.addElement(password);
content.addElement(role);
output.writeObject(new Message("USER_ADD",content));
output.flush();
System.out.println("CLIENT>>> "+name+ "USER_ADD");
}
synchronized static void Download(String ID,JFrame frame) throws IOException {
Jframe=frame;
Vector<String> content=new Vector<String>();
content.addElement(ID);
output.writeObject(new Message("DOWNLOAD",content));
output.flush();
System.out.println("CLIENT>>> CLIENT_FILE_DOWN");
}
synchronized static void Upload(String ID,String Creator,String description,String filename,JFrame frame) throws IOException{
Jframe=frame;
Vector<String> content=new Vector<String>();
File file=new File(filename.trim());
String fileName=file.getName();
String fileLength=String.valueOf(file.length());
content.addElement(ID);
content.addElement(Creator);
content.addElement(description);
content.addElement(fileName);
content.addElement(fileLength);
output.writeObject(new Message("UPLOAD",content));
output.flush();
FileInputStream fis=new FileInputStream(file);
byte[] sendBytes=new byte[1024];
int length=0;
while((length=fis.read(sendBytes,0,sendBytes.length))>0) {
output.write(sendBytes,0,length);
output.flush();
}
fis.close();
System.out.println("CLIENT>>> CLIENT_FILE_UP");
}
static int get_Rows() {
return row;
}
static int get_Rows2() {
return row2;
}
static String[][] get_Docs(){
return DocData;
}
static String[][] get_Users(){
return UserData;
}
static String get_Name() {
return user_name;
}
static String get_Role() {
return user_role;
}
}
服务端
import java.io.*;
import java.net.*;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Enumeration;
import java.util.Vector;
public class Server extends ServerSocket {
private static final int SERVER_PORT =12345;
public Server()throws IOException {
super(SERVER_PORT);
int count=1;
try {
while (true) {
Socket socket = accept();
System.out.println("Connection "+ " received from: "+socket.getInetAddress().getHostName() );
new ServerThread(socket,"Thread"+count);
count++;
}
}catch (IOException e) {
}finally {
close();
}
}
class ServerThread extends Thread {
private Socket client;
private String client_name;
private ObjectOutputStream output;
private ObjectInputStream input;
public ServerThread(Socket s,String client_name)throws IOException {
client = s;
output=new ObjectOutputStream(client.getOutputStream());
input=new ObjectInputStream(client.getInputStream());
System.out.println("Got I/O streams" );
System.out.println(client_name +" come in...");
this.client_name=client_name;
start();
}
public void run() {
String message="Connection successful!";
System.out.println(message);
try {
do {
Message msg =(Message) input.readObject();
message=msg.get_message();
if(message.equals("CLIENT>>> CLIENT_LOGIN")) {
String name=msg.get_content().elementAt(0);
String password=msg.get_content().elementAt(1);
if(DataProcessing.search(name, password)!=null) {
System.out.println(client_name+":");
System.out.println(message);
System.out.println(name);
String role=DataProcessing.search(name, password).getRole();
Vector<String> content=new Vector<String>();
content.addElement(role);
output.writeObject(new Message("LOGIN_TRUE",content));
output.flush();
System.out.println("SERVER>>> SERVER_LOGIN");
}
else {
output.writeObject(new Message("LOGIN_FALSE",null));
output.flush();
}
}
else if(message.equals("CLIENT>>> CLIENT_SELF_MOD")) {
String name=msg.get_content().elementAt(0);
String password=msg.get_content().elementAt(1);
String role=msg.get_content().elementAt(2);
System.out.println(client_name+":");
System.out.println("CLIENT_SELF_MOD");
if(DataProcessing.update(name, password, role)==true) {
Vector<String> content=new Vector<String>();
content.addElement(password);
output.writeObject(new Message("SELFCHANGE_TRUE",content));
output.flush();
System.out.println("SERVER>>> SERVER_SELF_MOD");
}
else {
output.writeObject(new Message("SELFCHANGE_FALSE",null));
output.flush();
}
}
else if(message.equals("displayUser")) {
Enumeration<User> e=DataProcessing.getAllUser();
User user;
Vector<String> content=new Vector<String>();
while(e.hasMoreElements()) {
user=e.nextElement();
content.addElement(user.getName());
content.addElement(user.getPassword());
content.addElement(user.getRole());
}
output.writeObject(new Message("displayedUser",content));
output.flush();
}
else if(message.equals("displayDoc")) {
Enumeration<Doc> e=DataProcessing.getAllDocs();
Doc doc;
Vector<String> content=new Vector<String>();
while(e.hasMoreElements()) {
doc=e.nextElement();
content.addElement(doc.getID());
content.addElement(doc.getCreator());
content.addElement(doc.getTimestamp().toString());
content.addElement(doc.getDescription());
content.addElement(doc.getFilename());
}
output.writeObject(new Message("displayedDoc",content));
output.flush();
}
else if(message.equals("USER_DELETE")) {
String name=msg.get_content().elementAt(0);
if(DataProcessing.delete(name)) {
output.writeObject(new Message("DELETE_TRUE",null));
output.flush();
System.out.println(client_name+":");
System.out.println("SERVER>>> "+name+" USER_DELETE");
}
else {
output.writeUTF("DELETE_FALSE");
output.flush();
}
}
else if(message.equals("USER_ADD")) {
String name=msg.get_content().elementAt(0);
String password=msg.get_content().elementAt(1);
String role=msg.get_content().elementAt(2);
if(DataProcessing.insert(name, password, role)) {
output.writeObject(new Message("ADD_TRUE",null));
output.flush();
System.out.println(client_name+":");
System.out.println("SERVER>>> "+name+" USER_ADD");
}
else {
output.writeObject(new Message("ADD_FALSE",null));
output.flush();
}
}
else if(message.equals("USER_UPDATE")) {
String name=msg.get_content().elementAt(0);
String password=msg.get_content().elementAt(1);
String role=msg.get_content().elementAt(2);
if(DataProcessing.update(name, password, role)) {
output.writeObject(new Message("UPDATE_TRUE",null));
output.flush();
System.out.println(client_name+":");
System.out.println("SERVER>>> "+name+" USER_UPDATE");
}
else {
output.writeObject(new Message("UPDATE_FALSE",null));
output.flush();
}
}
else if(message.equals("UPLOAD")) {
Timestamp timestamp=new Timestamp(System.currentTimeMillis());
String ID=msg.get_content().elementAt(0);
String Creator=msg.get_content().elementAt(1);
String description=msg.get_content().elementAt(2);
String filename=msg.get_content().elementAt(3);
Long fileLength=Long.parseLong(msg.get_content().elementAt(4));
FileOutputStream fos=new FileOutputStream(new File("C:\\uploadfile\\"+filename));
byte[] sendBytes=new byte[1024];
int transLen=0;
System.out.println("----开始接收文件<"+filename+">,文件大小为<"+fileLength+">----");
while(true) {
int read=0;
read=input.read(sendBytes,0,sendBytes.length);
if(read<=0) break;
transLen+=read;
System.out.println("接收文件进度"+100*transLen*1.0/fileLength+"%...");
fos.write(sendBytes,0,read);
fos.flush();
if(transLen>=fileLength) break;
}
fos.close();
System.out.println("----接收文件<"+filename+">成功----");
if(DataProcessing.insertDoc(ID, Creator, timestamp, description, filename)){
output.writeObject(new Message("UPLOAD_TRUE",null));
output.flush();
System.out.println(client_name+":");
System.out.println("SERVER>>> CLIENT_FILE_UP");
}
else {
output.writeObject(new Message("UPLOAD_FALSE",null));
output.flush();
}
}
else if(message.equals("DOWNLOAD")) {
String ID=msg.get_content().elementAt(0);
System.out.println(client_name+":");
System.out.println("SERVER>>> CLIENT_FILE_DOWN");
String filename=DataProcessing.searchDoc(ID).getFilename();
String filepath="C:\\uploadfile\\";
File file=new File(filepath+filename);
long fileLength=file.length();
Vector<String> content=new Vector<String>();
content.addElement(filename);
content.addElement(String.valueOf(fileLength));
output.writeObject(new Message("SERVER>>> CLIENT_FILE_DOWN",content));
output.flush();
FileInputStream fis=new FileInputStream(file);
byte[] sendBytes=new byte[1024];
int length=0;
while((length=fis.read(sendBytes,0,sendBytes.length))>0) {
output.write(sendBytes,0,length);
output.flush();
}
fis.close();
}
else ;
} while ( !message.equals( "CLIENT>>> CLIENT_LOGOUT" ) );
System.out.println(client_name+" LOGOUT!");
output.close();
input.close();
client.close();
}catch (SQLException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args)throws IOException {
String driverName="com.mysql.jdbc.Driver";
String url="jdbc:mysql://localhost:3306/document";
String user="root";
String password="123456";
try {
DataProcessing.connectToDatabase(driverName, url, user, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("Waiting for connection");
new Server();
}
}
消息类
实现对数据的封装和解封装
import java.io.Serializable;
import java.util.Vector;
public class Message implements Serializable{
String message;
Vector<String> content;
public Message(String message,Vector<String> content) {
this.message=message;
this.content=content;
}
public Vector<String> get_content() {
return content;
}
public String get_message() {
return message;
}
}
以下是需要完成的结果展示Java面向对象与多线程综合实验(七)之多线程
PS:本例实现了对服务器和客户端之间通信数据的封装但是未实现选项卡切换时对界面的更新操作