-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResponseServer.java
More file actions
255 lines (248 loc) · 8.25 KB
/
ResponseServer.java
File metadata and controls
255 lines (248 loc) · 8.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
package login;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeMap;
import java.security.*;
public class ResponseServer implements Serializable,AutoCloseable{
Map<String,String>database,added;
private ServerSocket listener;
static public final int DefaultPort=12345;
protected static final String DATAPATH="passwd";
protected final File passwd=new File(DATAPATH);
public static void main(String[] args){
ResponseServer Server=new ResponseServer();
// Timer clock=new Timer("AutoSave");
// clock.schedule(new AutoSaveTimerTask(Server) {
// @Override
// public void run() {
// this.obj.flush(0); // problem here
// //todo
// }
// }, 100);
int tid=0;
while(true){
try {
Socket soc=Server.accept();
new Thread(new ResponseWorker(soc,Server,true),
"Thread:"+tid++).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public Socket accept() throws IOException {
return listener.accept();
}
public ResponseServer(){
database=new TreeMap<>();
added=new TreeMap<>();
try {
listener=new ServerSocket(DefaultPort);
} catch (IOException e) {
e.printStackTrace();
}
if(!passwd.exists()){
try {
passwd.createNewFile();
} catch (IOException e) {
// todo
}
}else{
reload(passwd,0);
}
}
public void reload(File src,int method){
switch (method){
case 1->{
loadFromSerialization(src);
}
default -> {
loadFromText(src,false);
}
}
}
protected void loadFromText(File src,boolean show){
try {
BufferedReader reader=new BufferedReader(new FileReader(src));
String line=null;
while((line=reader.readLine())!=null){
String[]rels=line.split("\\|",2);
database.put(rels[0],rels[1]);
if(show) System.out.println(rels[0]+"|"+rels[1]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
protected void loadFromSerialization(File src){
try {
FileInputStream fileIn=new FileInputStream(src);
ObjectInputStream objIn=new ObjectInputStream(fileIn);
database=(TreeMap<String,String>)objIn.readObject();
} catch (IOException | ClassNotFoundException e) {
// todo
// impossible here
}
}
public void flush(int method){
switch (method){
case 1->{
saveBySerialization();
}
default -> {
saveByText();
}
}
}
protected void saveByText(){
try {
BufferedWriter writer=new BufferedWriter(new FileWriter(DATAPATH,true));
synchronized (this){
for (Map.Entry<String, String> entry : added.entrySet()) {
writer.write(entry.getKey() + " " + entry.getValue()+"\n");
System.out.println(entry.getKey() + " " + entry.getValue());
}
added.clear();
}
} catch (IOException e) {
e.printStackTrace();
}
}
protected void saveBySerialization(){
try {
FileOutputStream fileOut=new FileOutputStream(passwd);
ObjectOutputStream objOut=new ObjectOutputStream(fileOut);
objOut.writeObject(database);
objOut.flush();fileOut.flush();
objOut.close();fileOut.close();
} catch (IOException e) {
// todo
// impossible here
}
}
static public String md5(String raw){
try {
MessageDigest md=MessageDigest.getInstance("MD5");
md.update(raw.getBytes(StandardCharsets.UTF_8));
return new String(md.digest(), StandardCharsets.UTF_8);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
// impossible here
}
return raw;
}
static public int queryDescription(Map<String,String>database,String name,String psw,boolean login){
String psd=database.get(name);
if(login){
if(psd==null)return Response.fall_user_name_no_exist;
if(psd.equals(md5(psw)))return Response.succ_login;
else return Response.fall_no_match;
}else{
if(psd==null) {
// database.put(name,psw);
return Response.succ_registration;
}else { // error
return Response.fall_user_name_repeated;
}
}
}
@Override
public void close() throws Exception {
flush(0);
listener.close();
}
}
class ResponseWorker implements Runnable,AutoCloseable{
Socket socket;
final ResponseServer rserver;
Response.ResMsg response=null;
Request.ReqMsg request=null;
boolean autoSave;
public ResponseWorker(Socket client,ResponseServer rs,boolean AutoSave){
this.socket=client;
this.rserver=rs;
this.autoSave=AutoSave;
}
@Override
public void run() {
try {
this.getRequest().getResponse().close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* get the request msg by tcp socket
* get header first
* */
public ResponseWorker getRequest() throws IOException {
DataInputStream DIS=new DataInputStream(socket.getInputStream());
try {
request=Request.getMsg(ReProtocol.msgRead(DIS));
} catch (RePException e) {
e.printStackTrace();
}
// finally {
// BIS.close();
// }
return this;
}
public ResponseWorker getResponse() throws IOException {
int index=ResponseServer.queryDescription(rserver.database, request.name, request.psw,
request.id==3);
ReProtocol.Command cmd=request.id==3?
ReProtocol.Command.loginResponse:ReProtocol.Command.registrationResponse;
response=new Response.ResMsg(cmd,index>2,index);
DataOutputStream BOS=new DataOutputStream(socket.getOutputStream());
try {
BOS.write(new Response(response).getBytes());
BOS.flush();
if(index==1){ // registry
push();
}
// BOS.close();
} catch (RePException e) {
e.printStackTrace();
}
return this;
}
@Override
public void close(){
try {
socket.close();
if(!autoSave)return;
try {
BufferedWriter writer=new BufferedWriter(new FileWriter(ResponseServer.DATAPATH,true));
if(rserver.added.size()!=0){
synchronized (this.rserver){
for (Map.Entry<String, String> entry : rserver.added.entrySet()) {
writer.write(entry.getKey() + "|" + entry.getValue()+"\n");
}writer.flush();
rserver.added.clear();
}
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void push(){
synchronized (this.rserver){
this.rserver.database.put(request.name,ResponseServer.md5(request.psw));
this.rserver.added.put(request.name,ResponseServer.md5(request.psw));
}
}
}
abstract class AutoSaveTimerTask extends TimerTask{
public ResponseServer obj;
public AutoSaveTimerTask(ResponseServer svr){
this.obj=svr;
}
}