一个简单的支持多聊天室的多线程聊天程序
有几个需要注意的地方,一个是多线程的部分,然后获得inputstream和outputstream的顺序也很重要,其次ObjectOutputStream在发送的时候要记得调用reset()方法去清cache,否则不会传最新的。
caller class:
chatter class:
ClientGUI class:
ClientLogin class:
ClientThreadHandler class:
Coordinator class:
DataFrame class:
Secretary class:
Server class:
ServerGUI class:
ServerThreadHandler class:
caller class:
1
package networking;
2
3
import java.io.*;
4
import java.net.*;
5
import java.util.*;
6
7
/**
8
* This class implements Observer,which will send the updated users' list back
9
* to the user
10
*
11
* @author
12
* @version 1.0
13
*/
14
public class Caller implements Observer
15
{
16
/**
17
* Attributes
18
*/
19
private Socket socket;
20
private ObjectOutputStream oos;
21
22
/**
23
* Constructor
24
*/
25
public Caller(Socket socket, ObjectOutputStream oos)
26
{
27
this.socket = socket;
28
this.oos = oos;
29
}
30
31
/**
32
* getter
33
*
34
* @return Socket
35
*/
36
public Socket getSocket()
37
{
38
return this.socket;
39
}
40
41
/**
42
* getter
43
*
44
* @return ObjectOutputStream
45
*/
46
public ObjectOutputStream getObjectOutputStream()
47
{
48
return this.oos;
49
}
50
51
/*
52
* (non-Javadoc)
53
*
54
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
55
*/
56
public void update(Observable observable, Object object)
57
{
58
try
59
{
60
String room = (String)object;
61
Chatter chatter = Secretary.getSecretary().findChatter(socket);
62
if(chatter.getRoom().equals("Hall"))// if it is hall,send out
63
// the full list
64
{
65
try
66
{
67
DataFrame df = new DataFrame("UserList", Secretary
68
.getSecretary().getRegister());// full list
69
oos.reset();// clean cache of objectoutputstream
70
oos.writeObject(df);
71
oos.flush();
72
}
73
catch(InterruptedIOException iioe)
74
{
75
Secretary.getSecretary().deleteRecord(socket);
76
Coordinator.getCoordinator().notifyOffline(this,chatter.getRoom());
77
socket.close();
78
}
79
catch(IOException e)
80
{
81
Secretary.getSecretary().deleteRecord(socket);
82
Coordinator.getCoordinator().notifyOffline(this,chatter.getRoom());
83
socket.close();
84
}
85
}
86
else if(chatter.getRoom().equals(room))// notice the people in
87
// the same room that a
88
// guy logined in or
89
// logined out
90
{
91
try
92
{
93
DataFrame df = new DataFrame("UserList", Secretary
94
.getSecretary().getRegister(room));// only
95
// return
96
// the list
97
// of people
98
// in this
99
// room
100
oos.reset();
101
oos.writeObject(df);
102
oos.flush();
103
}
104
catch(InterruptedIOException iioe)// no response during
105
// the time
106
{
107
Secretary.getSecretary().deleteRecord(socket);
108
Coordinator.getCoordinator().notifyOffline(this,chatter.getRoom());
109
socket.close();
110
}
111
catch(IOException e)// network problem
112
{
113
Secretary.getSecretary().deleteRecord(socket);
114
Coordinator.getCoordinator().notifyOffline(this,chatter.getRoom());
115
socket.close();
116
}
117
}
118
}
119
catch(IOException e)// catch for exception that might be thrown from
120
// socket.close method
121
{
122
}
123
}
124
}
125

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

chatter class:
1
package networking;
2
3
import java.io.*;
4
import java.net.*;
5
6
/**
7
* Chatter class will hold the chatter's information,it implements
8
* Serializable,and it will be transported though network
9
*
10
* @author
11
* @version 1.0
12
*/
13
@SuppressWarnings("serial")
14
public class Chatter implements Serializable
15
{
16
/**
17
* Attributes
18
*/
19
private String ip;
20
private int port;
21
private String name;
22
private String room;
23
24
/**
25
* Constructor
26
*/
27
public Chatter(Socket socket, String name)
28
{
29
this.ip = socket.getInetAddress().toString();
30
this.port = socket.getPort();
31
this.name = name;
32
this.room = "Hall";
33
}
34
35
/**
36
* getter
37
*
38
* @return String
39
*/
40
public String getRoom()
41
{
42
return this.room;
43
}
44
45
/**
46
* setter
47
*
48
* @param room
49
*/
50
public void setRoom(String room)
51
{
52
this.room = room;
53
}
54
55
/**
56
* getter
57
*
58
* @return String
59
*/
60
public String getIP()
61
{
62
return this.ip;
63
}
64
65
/**
66
* getter
67
*
68
* @return String
69
*/
70
public String getName()
71
{
72
return this.name;
73
}
74
75
/**
76
* getter
77
*
78
* @return int
79
*/
80
public int getPort()
81
{
82
return this.port;
83
}
84
}
85

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

client class:
1
package networking;
2
3
import java.io.*;
4
import java.net.*;
5
6
/**
7
* client class,that will create the connection and send data use socket
8
* @author
9
* @version 1.0
10
*/
11
public class Client
12
{
13
/**
14
* Attributes
15
*/
16
private Socket socket;
17
private ObjectInputStream ois;
18
private ObjectOutputStream oos;
19
private static final int TIMEOUT_LENGTH = 300000;//max timeout number,5 minutes
20
21
/**
22
* Constructor
23
*/
24
public Client(String ip, int port) throws Exception
25
{
26
socket = new Socket(ip, port);
27
socket.setSoTimeout(TIMEOUT_LENGTH);
28
oos = new ObjectOutputStream(socket.getOutputStream());
29
ois = new ObjectInputStream(socket.getInputStream());
30
}
31
32
/**
33
* send method that will send the data to the other side
34
* @param type
35
* @param message
36
* @throws Exception
37
*/
38
public void send(String type, String message) throws Exception
39
{
40
oos.reset();
41
oos.writeObject(new DataFrame(type, message));
42
oos.flush();
43
}
44
45
/**
46
* getter
47
* @return ObjectInputStream
48
*/
49
public ObjectInputStream getOis()
50
{
51
return this.ois;
52
}
53
54
/**
55
* getter
56
* @return ObjectOutputStream
57
*/
58
public ObjectOutputStream getOos()
59
{
60
return this.oos;
61
}
62
63
/**
64
* getter
65
* @return Socket
66
*/
67
public Socket getSocket()
68
{
69
return this.socket;
70
}
71
}
72

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

ClientGUI class:
1
package networking;
2
3
import java.awt.*;
4
import java.awt.event.*;
5
import javax.swing.*;
6
import java.util.*;
7
8
/**
9
* clientGUI class,that will allow the user to send the message,change room,and
10
* will update the information for the user
11
*
12
* @author
13
* @version 1.0
14
*/
15
public class ClientGUI extends JFrame
16
{
17
/**
18
* Attributes
19
*/
20
private static final long serialVersionUID = 1L;
21
private JPanel jContentPane = null;
22
private JDesktopPane jDesktopPane = null;
23
private JButton jButton = null;
24
private Client client;
25
private JTextArea jTextArea = null;
26
private JScrollPane jScrollPane = null;
27
private JList jRoomList = null;
28
private JList jChatterList = null;
29
private JScrollPane jRoomScrollPane = null;
30
private JScrollPane jChatterScrollPane = null;
31
private JTextArea jContentTextArea = null;
32
private JScrollPane jContentScrollPane = null;
33
private JLabel jRoomLabel = null;
34
private JLabel jChatterLabel = null;
35
36
/**
37
* This is the default constructor
38
*/
39
public ClientGUI(Client client)
40
{
41
super();
42
this.client = client;
43
initialize();
44
this.addWindowListener(new WindowAdapter()
45
{
46
public void windowClosing(WindowEvent e)
47
{
48
System.exit(0);// close the application,it will cause the
49
// socket to be closed
50
}
51
});
52
}
53
54
/**
55
* This method initializes this
56
*
57
* @return void
58
*/
59
private void initialize()
60
{
61
this.setSize(664, 365);
62
this.setContentPane(getJContentPane());
63
this.setTitle("JFrame");
64
}
65
66
/**
67
* This method initializes jContentPane
68
*
69
* @return javax.swing.JPanel
70
*/
71
private JPanel getJContentPane()
72
{
73
if(jContentPane == null)
74
{
75
jContentPane = new JPanel();
76
jContentPane.setLayout(new BorderLayout());
77
jContentPane.add(getJDesktopPane(), BorderLayout.CENTER);
78
}
79
return jContentPane;
80
}
81
82
/**
83
* This method initializes jDesktopPane
84
*
85
* @return javax.swing.JDesktopPane
86
*/
87
private JDesktopPane getJDesktopPane()
88
{
89
if(jDesktopPane == null)
90
{
91
jChatterLabel = new JLabel();
92
jChatterLabel.setBounds(new Rectangle(536, 19, 42, 14));
93
jChatterLabel.setForeground(Color.red);
94
jChatterLabel.setText("To:All");
95
jRoomLabel = new JLabel();
96
jRoomLabel.setBounds(new Rectangle(20, 17, 130, 14));
97
jRoomLabel.setForeground(Color.red);
98
jRoomLabel.setText("Current room:hall");
99
jDesktopPane = new JDesktopPane();
100
jDesktopPane.add(getJButton(), null);
101
jDesktopPane.add(getJScrollPane(), null);
102
jDesktopPane.add(getJRoomScrollPane(), null);
103
jDesktopPane.add(getJChatterScrollPane(), null);
104
jDesktopPane.add(getJContentScrollPane(), null);
105
jDesktopPane.add(jRoomLabel, null);
106
jDesktopPane.add(jChatterLabel, null);
107
}
108
return jDesktopPane;
109
}
110
111
/**
112
* This method initializes jButton
113
*
114
* @return javax.swing.JButton
115
*/
116
private JButton getJButton()
117
{
118
if(jButton == null)
119
{
120
jButton = new JButton();
121
jButton.setBounds(new Rectangle(281, 286, 72, 21));
122
jButton.setText("Send");
123
jButton.addActionListener(new java.awt.event.ActionListener()
124
{
125
public void actionPerformed(java.awt.event.ActionEvent e)
126
{
127
try
128
{
129
String name = jChatterLabel.getText()
130
.replace("To:", "");
131
if(name.equals("All"))// message to all the people in
132
// that room
133
{
134
client.send("Public", jContentTextArea.getText());
135
}
136
else
137
// private message to a certain person
138
{
139
name = name.split("-")[0];
140
client.send("Private" + name, jContentTextArea
141
.getText());
142
}
143
}
144
catch(Exception ex)
145
{
146
System.out.println(ex.getMessage());
147
JOptionPane.showMessageDialog(jContentPane,
148
"Network problem", "No Title",
149
JOptionPane.ERROR_MESSAGE);
150
}
151
jContentTextArea.setText("");// clean the input text
152
// field
153
}
154
});
155
}
156
return jButton;
157
}
158
159
/**
160
* This method initializes jTextArea
161
*
162
* @return javax.swing.JTextArea
163
*/
164
private JTextArea getJTextArea()
165
{
166
if(jTextArea == null)
167
{
168
jTextArea = new JTextArea();
169
}
170
return jTextArea;
171
}
172
173
/**
174
* This method initializes jScrollPane
175
*
176
* @return javax.swing.JScrollPane
177
*/
178
private JScrollPane getJScrollPane()
179
{
180
if(jScrollPane == null)
181
{
182
jScrollPane = new JScrollPane();
183
jScrollPane.setBounds(new Rectangle(159, 46, 321, 150));
184
jScrollPane.setViewportView(getJTextArea());
185
jScrollPane
186
.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
187
}
188
return jScrollPane;
189
}
190
191
public void setText(String message)
192
{
193
this.jTextArea.setText(this.jTextArea.getText() + "\n" + message);
194
}
195
196
public void setChatterList(Vector<String> vector)
197
{
198
jChatterList.setListData(vector);
199
}
200
201
/**
202
* This method initializes jRoomList
203
*
204
* @return javax.swing.JList
205
*/
206
private JList getJRoomList()
207
{
208
if(jRoomList == null)
209
{
210
jRoomList = new JList();
211
Vector<String> vector = new Vector<String>();
212
vector.addElement("Hall");
213
vector.addElement("General Blab");
214
vector.addElement("No Holds Barred");
215
vector.addElement("Buy, Sell & Trade");
216
vector.addElement("Political Debating");
217
vector.addElement("Motherboards, RAM and CPUs");
218
vector.addElement("Video Cards and Computer Graphics");
219
vector.addElement("Overclocking");
220
vector.addElement("Sound Cards and Audio Devices");
221
vector.addElement("Input, Imaging and Storage Devices");
222
vector.addElement("Cases and Power Supplies");
223
vector.addElement("Software Et Al");
224
vector.addElement("Games and Game Consoles");
225
vector.addElement("Linux & BSD");
226
vector.addElement("Networking");
227
vector.addElement("Movies, TV, Animation and Home Theater");
228
vector.addElement("Misc. or Unknown");
229
vector.addElement("Application Dev, Programming and Scripting");
230
jRoomList.setListData(vector);
231
jRoomList
232
.addListSelectionListener(new javax.swing.event.ListSelectionListener()
233
{
234
public void valueChanged(
235
javax.swing.event.ListSelectionEvent e)
236
{
237
if(e.getValueIsAdjusting())
238
return;// only responds once,ignore the "leave
239
// focus" event but responds for the
240
// "get focus" event
241
if(jRoomList.getSelectedIndex() == -1)
242
return;
243
try
244
{
245
jRoomLabel.setText("Current room:"
246
+ (String)jRoomList.getSelectedValue());
247
client.send("Room", (String)jRoomList
248
.getSelectedValue());// apply to
249
// change room
250
// to the server
251
}
252
catch(Exception ex)
253
{
254
JOptionPane.showMessageDialog(jContentPane,
255
"Network problem", "No Title",
256
JOptionPane.ERROR_MESSAGE);
257
}
258
}
259
});
260
}
261
return jRoomList;
262
}
263
264
/**
265
* This method initializes jChatterList
266
*
267
* @return javax.swing.JList
268
*/
269
private JList getJChatterList()
270
{
271
if(jChatterList == null)
272
{
273
jChatterList = new JList();
274
jChatterList
275
.addListSelectionListener(new javax.swing.event.ListSelectionListener()
276
{
277
public void valueChanged(
278
javax.swing.event.ListSelectionEvent e)
279
{
280
if(e.getValueIsAdjusting())
281
return;
282
if(jChatterList.getSelectedIndex() == -1)
283
return;
284
try
285
{
286
jChatterLabel.setText("To:"
287
+ (String)jChatterList
288
.getSelectedValue());//change the receiver
289
}
290
catch(Exception ex)
291
{
292
JOptionPane.showMessageDialog(jContentPane,
293
"Network problem", "No Title",
294
JOptionPane.ERROR_MESSAGE);
295
}
296
}
297
});
298
}
299
return jChatterList;
300
}
301
302
/**
303
* This method initializes jRoomScrollPane
304
*
305
* @return javax.swing.JScrollPane
306
*/
307
private JScrollPane getJRoomScrollPane()
308
{
309
if(jRoomScrollPane == null)
310
{
311
jRoomScrollPane = new JScrollPane();
312
jRoomScrollPane.setLocation(new Point(11, 42));
313
jRoomScrollPane.setViewportView(getJRoomList());
314
jRoomScrollPane.setSize(new Dimension(128, 240));
315
}
316
return jRoomScrollPane;
317
}
318
319
/**
320
* This method initializes jChatterScrollPane
321
*
322
* @return javax.swing.JScrollPane
323
*/
324
private JScrollPane getJChatterScrollPane()
325
{
326
if(jChatterScrollPane == null)
327
{
328
jChatterScrollPane = new JScrollPane();
329
jChatterScrollPane.setLocation(new Point(495, 42));
330
jChatterScrollPane.setViewportView(getJChatterList());
331
jChatterScrollPane.setSize(new Dimension(128, 240));
332
}
333
return jChatterScrollPane;
334
}
335
336
/**
337
* This method initializes jContentTextArea
338
*
339
* @return javax.swing.JTextArea
340
*/
341
private JTextArea getJContentTextArea()
342
{
343
if(jContentTextArea == null)
344
{
345
jContentTextArea = new JTextArea();
346
}
347
return jContentTextArea;
348
}
349
350
/**
351
* This method initializes jContentScrollPane
352
*
353
* @return javax.swing.JScrollPane
354
*/
355
private JScrollPane getJContentScrollPane()
356
{
357
if(jContentScrollPane == null)
358
{
359
jContentScrollPane = new JScrollPane();
360
jContentScrollPane.setBounds(new Rectangle(157, 215, 321, 56));
361
jContentScrollPane.setViewportView(getJContentTextArea());
362
}
363
return jContentScrollPane;
364
}
365
}
366

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

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

ClientLogin class:
1
package networking;
2
3
import java.awt.*;
4
import javax.swing.*;
5
import java.awt.Color;
6
import java.awt.event.*;
7
8
/**
9
* clientlogin is the login gui class
10
*
11
* @author
12
* @version 1.0
13
*/
14
public class ClientLogin extends JFrame
15
{
16
/**
17
* Attributes
18
*/
19
private static final long serialVersionUID = 1L;
20
private JPanel jContentPane = null;
21
private JDesktopPane jDesktopPane = null;
22
private JLabel jHostLabel = null;
23
private JTextField jHostTextField = null;
24
private JLabel jNameLabel = null;
25
private JTextField jNameTextField = null;
26
private JButton jButton = null;
27
28
/**
29
* This is the default constructor
30
*/
31
public ClientLogin()
32
{
33
super();
34
initialize();
35
this.addWindowListener(new WindowAdapter()
36
{
37
public void windowClosing(WindowEvent e)
38
{
39
System.exit(0);
40
}
41
});
42
}
43
44
/**
45
* This method initializes this
46
*
47
* @return void
48
*/
49
private void initialize()
50
{
51
this.setSize(481, 290);
52
this.setContentPane(getJContentPane());
53
this.setTitle("JFrame");
54
}
55
56
/**
57
* This method initializes jContentPane
58
*
59
* @return javax.swing.JPanel
60
*/
61
private JPanel getJContentPane()
62
{
63
if(jContentPane == null)
64
{
65
jContentPane = new JPanel();
66
jContentPane.setLayout(new BorderLayout());
67
jContentPane.add(getJDesktopPane(), BorderLayout.CENTER);
68
}
69
return jContentPane;
70
}
71
72
/**
73
* This method initializes jDesktopPane
74
*
75
* @return javax.swing.JDesktopPane
76
*/
77
private JDesktopPane getJDesktopPane()
78
{
79
if(jDesktopPane == null)
80
{
81
jNameLabel = new JLabel();
82
jNameLabel.setBounds(new Rectangle(79, 117, 55, 14));
83
jNameLabel.setForeground(Color.red);
84
jNameLabel.setText("Your name:");
85
jHostLabel = new JLabel();
86
jHostLabel.setBounds(new Rectangle(79, 38, 39, 14));
87
jHostLabel.setForeground(Color.red);
88
jHostLabel.setText("Host IP:");
89
jDesktopPane = new JDesktopPane();
90
jDesktopPane.add(jHostLabel, null);
91
jDesktopPane.add(getJHostTextField(), null);
92
jDesktopPane.add(jNameLabel, null);
93
jDesktopPane.add(getJNameTextField(), null);
94
jDesktopPane.add(getJButton(), null);
95
}
96
return jDesktopPane;
97
}
98
99
public JPanel getContentPane()
100
{
101
return this.jContentPane;
102
}
103
104
/**
105
* This method initializes jHostTextField
106
*
107
* @return javax.swing.JTextField
108
*/
109
private JTextField getJHostTextField()
110
{
111
if(jHostTextField == null)
112
{
113
jHostTextField = new JTextField();
114
jHostTextField.setBounds(new Rectangle(150, 38, 136, 20));
115
jHostTextField.setText("127.0.0.1");
116
}
117
return jHostTextField;
118
}
119
120
/**
121
* This method initializes jNameTextField
122
*
123
* @return javax.swing.JTextField
124
*/
125
private JTextField getJNameTextField()
126
{
127
if(jNameTextField == null)
128
{
129
jNameTextField = new JTextField();
130
jNameTextField.setBounds(new Rectangle(149, 117, 137, 20));
131
}
132
return jNameTextField;
133
}
134
135
/**
136
* This method initializes jButton
137
*
138
* @return javax.swing.JButton
139
*/
140
private JButton getJButton()
141
{
142
if(jButton == null)
143
{
144
jButton = new JButton();
145
jButton.setBounds(new Rectangle(187, 168, 59, 23));
146
jButton.setText("Login");
147
jButton.addActionListener(new java.awt.event.ActionListener()
148
{
149
public void actionPerformed(java.awt.event.ActionEvent e)
150
{
151
try
152
{
153
// login
154
Client client = new Client(jHostTextField.getText(),
155
2008);
156
client.send("Login", jNameTextField.getText());
157
ClientGUI cg = new ClientGUI(client);
158
ClientThreadHandler cth = new ClientThreadHandler(
159
client.getSocket(), client.getOis(), cg,
160
ClientLogin.this);
161
Thread thread = new Thread(cth);
162
thread.start();// starts a thread to listen the
163
// responses from the server
164
}
165
catch(Exception ex)
166
{
167
JOptionPane.showMessageDialog(jContentPane,
168
"Wrong ip address", "No Title",
169
JOptionPane.ERROR_MESSAGE);
170
}
171
}
172
});
173
}
174
return jButton;
175
}
176
}
177

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

ClientThreadHandler class:
1
package networking;
2
3
import java.io.*;
4
import java.net.*;
5
import java.util.*;
6
import javax.swing.JOptionPane;
7
8
/**
9
* client thread that will listent the responses from the server,and update the
10
* information to the gui class
11
*
12
* @author
13
* @version 1.0
14
*/
15
public class ClientThreadHandler implements Runnable
16
{
17
/**
18
* Attributes
19
*/
20
private Socket socket;
21
private ObjectInputStream ois;
22
private ClientGUI clientGUI;
23
private ClientLogin clientLogin;
24
25
/**
26
* Constructor
27
*/
28
public ClientThreadHandler(Socket socket, ObjectInputStream ois,
29
ClientGUI clientGUI, ClientLogin clientLogin)
30
{
31
this.socket = socket;
32
this.ois = ois;
33
this.clientGUI = clientGUI;
34
this.clientLogin = clientLogin;
35
}
36
37
/* (non-Javadoc)
38
* @see java.lang.Runnable#run()
39
*/
40
@SuppressWarnings("unchecked")
41
public void run()
42
{
43
while(true)
44
{
45
try
46
{
47
try
48
{
49
DataFrame df = (DataFrame)ois.readObject();
50
if(df.getType().equals("Error"))
51
{
52
String error = (String)df.getObject();
53
if(error.equals("Name already exists"))//name exists
54
{
55
JOptionPane.showMessageDialog(clientLogin
56
.getContentPane(), error, "No Title",
57
JOptionPane.ERROR_MESSAGE);
58
clientLogin.setVisible(true);
59
clientGUI.setVisible(false);
60
}
61
else if(error.equals("IP and port already exist"))//ip and port exist
62
{
63
JOptionPane.showMessageDialog(clientLogin
64
.getContentPane(), error, "No Title",
65
JOptionPane.ERROR_MESSAGE);
66
clientLogin.setVisible(true);
67
clientGUI.setVisible(false);
68
}
69
}
70
else//ok to login
71
{
72
clientLogin.setVisible(false);
73
clientGUI.setVisible(true);
74
}
75
if(df.getType().equals("Message"))//message from the server
76
{
77
clientGUI.setText((String)df.getObject());
78
}
79
else if(df.getType().startsWith("UserList"))//userlist from the server
80
{
81
ArrayList<Chatter> al = (ArrayList<Chatter>)df
82
.getObject();
83
Vector<String> vector = new Vector<String>();
84
vector.addElement("All");//always add "All" option for the user
85
for(int i = 0; i < al.size(); i++)
86
{
87
vector.addElement(al.get(i).getName() + "-("
88
+ al.get(i).getRoom() + ")");
89
}
90
clientGUI.setChatterList(vector);
91
}
92
}
93
catch(Exception e)
94
{
95
socket.close();
96
}
97
}
98
catch(IOException e)
99
{
100
}
101
}
102
}
103
}
104

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

Coordinator class:
1
package networking;
2
3
import java.io.IOException;
4
import java.io.InterruptedIOException;
5
import java.io.ObjectOutputStream;
6
import java.net.*;
7
import java.util.*;
8
9
/**
10
* coordinator class that works as a coordinator,which will notice the users
11
* when a new user login or logout,or a user wants to send a message,etc
12
*
13
* @author
14
* @version 1.0
15
*/
16
public class Coordinator
17
{
18
/**
19
* Attributes
20
*/
21
private ArrayList<Caller> callers;
22
private MessageCenter mc;
23
public static Coordinator coordinator;
24
private class MessageCenter extends Observable
25
{
26
public void setChanged()
27
{
28
super.setChanged();
29
}
30
}
31
32
/**
33
* method that will return all the sockets connected
34
*
35
* @return
36
*/
37
public ArrayList<Socket> getSockets()
38
{
39
ArrayList<Socket> sockets = new ArrayList<Socket>();
40
synchronized(callers)// add a lock,to make sure that when one thread
41
// is dealing with the list,other threads which
42
// want to change the list must wait
43
{
44
for(int i = 0; i < callers.size(); i++)
45
{
46
sockets.add(callers.get(i).getSocket());
47
}
48
}
49
return sockets;
50
}
51
52
/**
53
* Constructor
54
*/
55
private Coordinator()
56
{
57
callers = new ArrayList<Caller>();
58
mc = new MessageCenter();
59
}
60
61
/**
62
* Singleton pattern that will only hold one instance of this class
63
*
64
* @return Coordinator
65
*/
66
public static Coordinator getCoordinator()
67
{
68
if(coordinator == null)
69
{
70
coordinator = new Coordinator();
71
}
72
return coordinator;
73
}
74
75
/**
76
* method that will send a private message from the sender to the receiver
77
*
78
* @param message
79
* @param receiver
80
* @param sender
81
*/
82
public void sendPrivateMessage(String message, Chatter receiver,
83
Chatter sender)
84
{
85
if(message == null)
86
{
87
return;
88
}
89
if(receiver == null)// no such a receiver in the user list
90
{
91
synchronized(callers)// lock to protect the data integrity
92
{
93
for(Caller caller: callers)
94
{
95
if(caller.getSocket().getInetAddress().toString().equals(
96
sender.getIP()))// ip is the same
97
{
98
if(caller.getSocket().getPort() == sender.getPort())// port
99
// is
100
// the
101
// same
102
{
103
try
104
{
105
try
106
{
107
ObjectOutputStream oos = caller
108
.getObjectOutputStream();
109
oos.reset();
110
oos.writeObject(new DataFrame("Error",
111
"No such name"));// send error
112
// message back
113
// to the sender
114
oos.flush();
115
}
116
catch(InterruptedIOException iioe)
117
{
118
synchronized(this)
119
{
120
Chatter chatter = Secretary
121
.getSecretary().findChatter(
122
caller.getSocket());
123
Secretary.getSecretary().deleteRecord(
124
caller.getSocket());
125
this.notifyOffline(caller, chatter
126
.getRoom());
127
}
128
caller.getSocket().close();
129
}
130
catch(IOException e)
131
{
132
synchronized(this)
133
{
134
Chatter chatter = Secretary
135
.getSecretary().findChatter(
136
caller.getSocket());
137
Secretary.getSecretary().deleteRecord(
138
caller.getSocket());
139
this.notifyOffline(caller, chatter
140
.getRoom());
141
}
142
caller.getSocket().close();
143
}
144
}
145
catch(IOException e)
146
{
147
}
148
}
149
}
150
}
151
}
152
}
153
else
154
// the receiver exists
155
{
156
synchronized(callers)// lock to protect the data integrity
157
{
158
for(Caller caller: callers)
159
{
160
if(caller.getSocket().getInetAddress().toString().equals(
161
receiver.getIP()))
162
{
163
if(caller.getSocket().getPort() == receiver.getPort())
164
{
165
try
166
{
167
try
168
{
169
ObjectOutputStream oos = caller
170
.getObjectOutputStream();
171
oos.reset();
172
oos.writeObject(new DataFrame("Message",
173
"From " + sender.getName() + " To "
174
+ receiver.getName() + ": "
175
+ message));// send the
176
// private
177
// message
178
oos.flush();
179
}
180
catch(InterruptedIOException iioe)// time is
181
// up
182
{
183
synchronized(this)
184
{
185
Chatter chatter = Secretary
186
.getSecretary().findChatter(
187
caller.getSocket());
188
Secretary.getSecretary().deleteRecord(
189
caller.getSocket());
190
this.notifyOffline(caller, chatter
191
.getRoom());
192
}
193
caller.getSocket().close();
194
}
195
catch(IOException e)// disconnected
196
{
197
synchronized(this)
198
{
199
Chatter chatter = Secretary
200
.getSecretary().findChatter(
201
caller.getSocket());
202
Secretary.getSecretary().deleteRecord(
203
caller.getSocket());
204
this.notifyOffline(caller, chatter
205
.getRoom());
206
}
207
caller.getSocket().close();
208
}
209
}
210
catch(IOException e)
211
{
212
}
213
}
214
}
215
}
216
}
217
}
218
}
219
220
/**
221
* method that will send the public message to all the people in that room
222
*
223
* @param chatter
224
* @param message
225
*/
226
public void sendPublicMessage(Chatter chatter, String message)
227
{
228
if(message == null)
229
{
230
return;
231
}
232
ArrayList<Caller> disconnects = new ArrayList<Caller>();
233
synchronized(callers)// lock to protect the data integrity
234
{
235
for(Caller caller: callers)
236
{
237
Chatter targetChatter = Secretary.getSecretary().findChatter(
238
caller.getSocket());
239
if(targetChatter.getRoom().equals(chatter.getRoom()))
240
{
241
try
242
{
243
ObjectOutputStream oos = caller.getObjectOutputStream();
244
oos.reset();
245
oos.writeObject(new DataFrame("Message", "From "
246
+ chatter.getName() + " To " + "all" + ": "
247
+ message));// send the public message
248
oos.flush();
249
}
250
catch(InterruptedIOException iioe)
251
{
252
disconnects.add(caller);
253
}
254
catch(IOException e)
255
{
256
disconnects.add(caller);
257
}
258
}
259
}
260
}
261
for(Caller caller: disconnects)
262
{
263
try
264
{
265
synchronized(this)
266
{
267
Chatter targetChatter = Secretary.getSecretary()
268
.findChatter(caller.getSocket());
269
Secretary.getSecretary().deleteRecord(caller.getSocket());
270
this.notifyOffline(caller, targetChatter.getRoom());// notify
271
// the
272
// users
273
// that
274
// this
275
// user has left
276
}
277
caller.getSocket().close();
278
}
279
catch(IOException e)
280
{
281
}
282
}
283
}
284
285
/**
286
* method that will notify all the people in the user's previous room that
287
* the user has left,and it will notify all the people in the user's next
288
* room that the user has joined,and it will also notify the people in the
289
* hall that the user has changed his room
290
*
291
* @param previousRoom
292
* @param nextRoom
293
*/
294
public void updateRooms(String previousRoom, String nextRoom)
295
{
296
synchronized(this.mc)
297
{
298
this.mc.setChanged();
299
this.mc.notifyObservers(previousRoom);
300
this.mc.setChanged();
301
this.mc.notifyObservers(nextRoom);
302
}
303
}
304
305
/**
306
* method that will find the chatter through the socket
307
*
308
* @param socket
309
* @return
310
*/
311
public Caller findCaller(Socket socket)
312
{
313
synchronized(callers)
314
{
315
for(Caller caller: callers)
316
{
317
if(caller.getSocket().getInetAddress().equals(
318
socket.getInetAddress())
319
&& caller.getSocket().getPort() == socket.getPort())
320
{
321
return caller;
322
}
323
}
324
}
325
return null;
326
}
327
328
/**
329
* method that will notify all the people in the hall that a new user has
330
* joined
331
*
332
* @param caller
333
*/
334
public void notifyOnline(Caller caller)
335
{
336
if(caller != null)
337
{
338
synchronized(this)
339
{
340
synchronized(this.callers)
341
{
342
this.callers.add(caller);
343
}
344
synchronized(this.mc)
345
{
346
this.mc.addObserver(caller);
347
this.mc.setChanged();
348
this.mc.notifyObservers("Hall");
349
}
350
}
351
}
352
}
353
354
/**
355
* method that will notify the people in the user's room that he has
356
* left,and it will also notify all the people in the hall that the user has
357
* left
358
*
359
* @param caller
360
* @param room
361
*/
362
public void notifyOffline(Caller caller, String room)
363
{
364
if(caller != null)
365
{
366
synchronized(this)
367
{
368
synchronized(this.callers)
369
{
370
this.callers.remove(caller);
371
}
372
synchronized(this.mc)
373
{
374
this.mc.deleteObserver(caller);
375
this.mc.setChanged();
376
this.mc.notifyObservers(room);
377
}
378
}
379
}
380
}
381
382
/**
383
* method that will return the count of all the callers(connected endpoint)
384
*
385
* @return
386
*/
387
public int count()
388
{
389
synchronized(this.callers)
390
{
391
return this.callers.size();
392
}
393
}
394
}
395

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

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

DataFrame class:
1
package networking;
2
3
import java.io.*;
4
5
/**
6
* class that will be used to transport through the network
7
*
8
* @author
9
* @version 1.0
10
*/
11
@SuppressWarnings("serial")
12
public class DataFrame implements Serializable
13
{
14
/**
15
* Attributes
16
*/
17
private String type;
18
private Object object;
19
20
/**
21
* Constructor
22
*/
23
public DataFrame(String type, Object object)
24
{
25
this.type = type;
26
this.object = object;
27
}
28
29
/**
30
* getter
31
*
32
* @return Objecct
33
*/
34
public Object getObject()
35
{
36
return this.object;
37
}
38
39
/**
40
* getter
41
*
42
* @return String
43
*/
44
public String getType()
45
{
46
return this.type;
47
}
48
}
49

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

Secretary class:
1
package networking;
2
3
import java.net.Socket;
4
import java.util.*;
5
6
/**
7
* class that will hold all the current connected chatter's information
8
*
9
* @author
10
* @version 1.0
11
*/
12
public class Secretary
13
{
14
/**
15
* Attributes
16
*/
17
private ArrayList<Chatter> register;
18
private static Secretary secretary;
19
20
/**
21
* Constructor
22
*/
23
private Secretary()
24
{
25
register = new ArrayList<Chatter>();
26
}
27
28
/**
29
* singleton pattern that will only hold one instance of this class
30
*
31
* @return
32
*/
33
public static Secretary getSecretary()
34
{
35
if(secretary == null)
36
{
37
secretary = new Secretary();
38
}
39
return secretary;
40
}
41
42
/**
43
* method that will add the record to the list
44
*
45
* @param socket
46
* @param name
47
*/
48
public void addRecord(Socket socket, String name)
49
{
50
Chatter chatter = new Chatter(socket, name);
51
synchronized(this.register)
52
{
53
this.register.add(chatter);
54
}
55
}
56
57
/**
58
* method that will delete the record in the list
59
*
60
* @param socket
61
*/
62
public void deleteRecord(Socket socket)
63
{
64
synchronized(this.register)
65
{
66
Chatter targetChatter = null;
67
for(Chatter chatter: this.register)
68
{
69
if(chatter.getIP().equals(socket.getInetAddress().toString()))
70
{
71
if(chatter.getPort() == socket.getPort())
72
{
73
targetChatter = chatter;
74
}
75
}
76
}
77
if(targetChatter != null)
78
{
79
this.register.remove(targetChatter);
80
}
81
}
82
}
83
84
/**
85
* method that will find the chatter through his name
86
*
87
* @param name
88
* @return
89
*/
90
public Chatter findChatter(String name)
91
{
92
synchronized(this.register)
93
{
94
for(Chatter chatter: this.register)
95
{
96
if(chatter.getName().equals(name))
97
{
98
return chatter;
99
}
100
}
101
}
102
return null;
103
}
104
105
/**
106
* method that will find the chatter through his ip and port
107
*
108
* @param socket
109
* @return
110
*/
111
public Chatter findChatter(Socket socket)
112
{
113
synchronized(this.register)
114
{
115
for(Chatter chatter: this.register)
116
{
117
if(chatter.getIP().equals(socket.getInetAddress().toString()))
118
{
119
if(chatter.getPort() == socket.getPort())
120
{
121
return chatter;
122
}
123
}
124
}
125
}
126
return null;
127
}
128
129
/**
130
* method that will check to see if the name has existed or not
131
*
132
* @param name
133
* @return
134
*/
135
public boolean isExist(String name)
136
{
137
synchronized(this.register)
138
{
139
for(Chatter chatter: this.register)
140
{
141
if(chatter.getName().equals(name))
142
{
143
return true;
144
}
145
}
146
}
147
return false;
148
}
149
150
/**
151
* method that will return the list of all the chatters
152
*
153
* @return
154
*/
155
public ArrayList<Chatter> getRegister()
156
{
157
return this.register;
158
}
159
160
/**
161
* method that will return the list of all the chatters in the particular
162
* room
163
*
164
* @param room
165
* @return
166
*/
167
public ArrayList<Chatter> getRegister(String room)
168
{
169
ArrayList<Chatter> roomRegister = new ArrayList<Chatter>();
170
synchronized(this.register)
171
{
172
if(room.equals("Hall"))
173
{
174
return this.register;
175
}
176
else
177
{
178
for(Chatter chatter: this.register)
179
{
180
if(chatter.getRoom().equals(room))
181
{
182
roomRegister.add(chatter);
183
}
184
}
185
}
186
}
187
return roomRegister;
188
}
189
}
190

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

Server class:
1
package networking;
2
3
import java.io.*;
4
import java.net.*;
5
6
/**
7
* method that will start the server,and begin to listen to the connection
8
* requests and create new threads to deal with those requests
9
*
10
* @author
11
* @version 1.0
12
*/
13
public class Server
14
{
15
/**
16
* Attributes
17
*/
18
private ServerSocket ss;
19
private static final int BIND_PORT = 2008;
20
private static final int MAX_CONNECTIONS = 1000;
21
private static ThreadGroup connections = new ThreadGroup("connections");
22
private ServerGUI serverGUI;
23
24
/**
25
* Constructor
26
*/
27
public Server(ServerGUI serverGUI)
28
{
29
this.serverGUI = serverGUI;
30
}
31
32
/**
33
* method to start the server
34
*/
35
public void run()
36
{
37
try
38
{
39
ss = new ServerSocket(BIND_PORT);
40
while(true)
41
{
42
try
43
{
44
Socket socket = ss.accept();
45
if(connections.activeCount() >= MAX_CONNECTIONS)// if the
46
// server
47
// has
48
// reached
49
// the max
50
// connections,then
51
// drop the
52
// request
53
{
54
socket.close();
55
}
56
else
57
{
58
ServerThreadHandler sth = new ServerThreadHandler(
59
socket, serverGUI);
60
Thread thread = new Thread(connections, sth);
61
thread.start();// create new thread to deal with the
62
// new connection
63
}
64
}
65
catch(IOException e)
66
{
67
continue;
68
}
69
}
70
}
71
catch(IOException e)
72
{
73
}
74
}
75
76
/**
77
* main method to start the application
78
*
79
* @param args
80
*/
81
public static void main(String[] args)
82
{
83
ServerGUI serverGUI = new ServerGUI();
84
serverGUI.setVisible(true);
85
Server server = new Server(serverGUI);
86
server.run();
87
}
88
}
89

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

ServerGUI class:
1
package networking;
2
3
import java.awt.*;
4
import javax.swing.*;
5
6
/**
7
* server gui class that will display the updated information
8
* @author
9
* @version 1.0
10
*/
11
public class ServerGUI extends JFrame
12
{
13
/**
14
* Attributes
15
*/
16
private static final long serialVersionUID = 1L;
17
private JPanel jContentPane = null;
18
private JDesktopPane jDesktopPane = null;
19
private JScrollPane jScrollPane = null;
20
private JTextArea jTextArea = null;
21
22
/**
23
* This is the default constructor
24
*/
25
public ServerGUI()
26
{
27
super();
28
initialize();
29
}
30
31
/**
32
* This method initializes this
33
*
34
* @return void
35
*/
36
private void initialize()
37
{
38
this.setSize(579, 356);
39
this.setContentPane(getJContentPane());
40
this.setTitle("JFrame");
41
}
42
43
/**
44
* This method initializes jContentPane
45
*
46
* @return javax.swing.JPanel
47
*/
48
private JPanel getJContentPane()
49
{
50
if(jContentPane == null)
51
{
52
jContentPane = new JPanel();
53
jContentPane.setLayout(new BorderLayout());
54
jContentPane.add(getJDesktopPane(), BorderLayout.CENTER);
55
}
56
return jContentPane;
57
}
58
59
/**
60
* This method initializes jDesktopPane
61
*
62
* @return javax.swing.JDesktopPane
63
*/
64
private JDesktopPane getJDesktopPane()
65
{
66
if(jDesktopPane == null)
67
{
68
jDesktopPane = new JDesktopPane();
69
jDesktopPane.add(getJScrollPane(), null);
70
}
71
return jDesktopPane;
72
}
73
74
/**
75
* This method initializes jScrollPane
76
*
77
* @return javax.swing.JScrollPane
78
*/
79
private JScrollPane getJScrollPane()
80
{
81
if(jScrollPane == null)
82
{
83
jScrollPane = new JScrollPane();
84
jScrollPane.setBounds(new Rectangle(96, 14, 391, 266));
85
jScrollPane.setViewportView(getJTextArea());
86
}
87
return jScrollPane;
88
}
89
90
/**
91
* This method initializes jTextArea
92
*
93
* @return javax.swing.JTextArea
94
*/
95
private JTextArea getJTextArea()
96
{
97
if(jTextArea == null)
98
{
99
jTextArea = new JTextArea();
100
}
101
return jTextArea;
102
}
103
104
/**
105
* method to add the text to the text field in the gui
106
* @param text
107
*/
108
public void addText(String text)
109
{
110
if(this.jTextArea.getText().equals(""))
111
{
112
this.jTextArea.setText(text);
113
}
114
else
115
{
116
this.jTextArea.setText(this.jTextArea.getText() + "\n" + text);
117
}
118
}
119
}
120

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

ServerThreadHandler class:
1
package networking;
2
3
import java.io.*;
4
import java.net.*;
5
6
/**
7
* class that has the run method that the thread will use
8
*
9
* @author
10
* @version 1.0
11
*/
12
public class ServerThreadHandler implements Runnable
13
{
14
/**
15
* Attributes
16
*/
17
private Socket socket;
18
private ServerGUI serverGUI;
19
private static final int TIMEOUT_LENGTH = 300000;
20
21
/**
22
* Constructor
23
*/
24
public ServerThreadHandler(Socket socket, ServerGUI serverGUI)
25
{
26
this.socket = socket;
27
try
28
{
29
this.socket.setSoTimeout(TIMEOUT_LENGTH);
30
}
31
catch(SocketException se)
32
{
33
}
34
this.serverGUI = serverGUI;
35
}
36
37
/*
38
* (non-Javadoc)
39
*
40
* @see java.lang.Runnable#run()
41
*/
42
public void run()
43
{
44
try
45
{
46
ObjectInputStream ois = new ObjectInputStream(socket
47
.getInputStream());
48
ObjectOutputStream oos = new ObjectOutputStream(socket
49
.getOutputStream());
50
try
51
{
52
while(true)
53
{
54
DataFrame df = (DataFrame)ois.readObject();
55
if(df.getType().equals("Login"))
56
{
57
String name = (String)df.getObject();
58
if(Secretary.getSecretary().isExist(name))
59
{
60
oos.reset();
61
oos.writeObject(new DataFrame("Error",
62
"Name already exists"));// name exists
63
oos.flush();
64
}
65
else if(Coordinator.getCoordinator().findCaller(socket) != null)
66
{
67
oos.reset();
68
oos.writeObject(new DataFrame("Error",
69
"IP and port already exist"));// ip and
70
// port
71
// exist
72
oos.flush();
73
}
74
else
75
{
76
Secretary.getSecretary().addRecord(socket, name);
77
Coordinator.getCoordinator().notifyOnline(
78
new Caller(socket, oos));
79
this.serverGUI.addText(name + " logined");// login
80
// request
81
}
82
continue;
83
}
84
if(Coordinator.getCoordinator().findCaller(socket) == null)
85
{
86
oos.reset();
87
oos.writeObject(new DataFrame("Error",
88
"Must login first"));// login validation
89
oos.flush();
90
}
91
else if(df.getType().equals("Room"))
92
{
93
String nextRoom = (String)df.getObject();
94
Chatter chatter = Secretary.getSecretary().findChatter(
95
socket);
96
String previousRoom = chatter.getRoom();
97
chatter.setRoom(nextRoom);
98
Coordinator.getCoordinator().updateRooms(previousRoom,
99
nextRoom);
100
this.serverGUI.addText(chatter.getName()
101
+ " changed room to" + chatter.getRoom());// change
102
// room
103
// request
104
}
105
else if(df.getType().equals("Public"))
106
{
107
String message = (String)df.getObject();
108
Chatter chatter = Secretary.getSecretary().findChatter(
109
socket);
110
Coordinator.getCoordinator().sendPublicMessage(chatter,
111
message);
112
this.serverGUI.addText(chatter.getName()
113
+ " sent public message:" + message);// send
114
// public
115
// message
116
// request
117
}
118
else if(df.getType().startsWith("Private"))
119
{
120
Chatter sender = Secretary.getSecretary().findChatter(
121
socket);
122
String name = df.getType().replaceFirst("Private", "");
123
Chatter receiver = Secretary.getSecretary()
124
.findChatter(name);
125
String message = (String)df.getObject();
126
Coordinator.getCoordinator().sendPrivateMessage(
127
message, receiver, sender);
128
this.serverGUI.addText(sender.getName()
129
+ " sent private message:" + message + " to:"
130
+ receiver.getName());// send private message
131
// request
132
}
133
else if(df.getType().equals("Logout"))
134
{
135
synchronized(Coordinator.getCoordinator())
136
{
137
Chatter chatter = Secretary.getSecretary()
138
.findChatter(socket);
139
Secretary.getSecretary().deleteRecord(socket);
140
Coordinator.getCoordinator().notifyOffline(
141
Coordinator.getCoordinator().findCaller(
142
socket), chatter.getRoom());
143
this.serverGUI.addText(chatter.getName()
144
+ " loged out");// logout request
145
}
146
}
147
else
148
{
149
oos.reset();
150
oos.writeObject(new DataFrame("Error", df.getType()));
151
oos.flush();
152
}
153
}
154
}
155
catch(ClassNotFoundException e)
156
{
157
if(Coordinator.getCoordinator().findCaller(socket) != null)
158
{
159
synchronized(Coordinator.getCoordinator())
160
{
161
Chatter chatter = Secretary.getSecretary().findChatter(
162
socket);
163
Secretary.getSecretary().deleteRecord(socket);
164
Coordinator.getCoordinator()
165
.notifyOffline(
166
Coordinator.getCoordinator()
167
.findCaller(socket),
168
chatter.getRoom());
169
this.serverGUI
170
.addText(chatter.getName() + " loged out");// exception
171
// that
172
// will
173
// notify
174
// the
175
// other
176
// chatters
177
}
178
}
179
socket.close();
180
}
181
catch(InterruptedIOException iioe)
182
{
183
if(Coordinator.getCoordinator().findCaller(socket) != null)
184
{
185
synchronized(Coordinator.getCoordinator())
186
{
187
Chatter chatter = Secretary.getSecretary().findChatter(
188
socket);
189
Secretary.getSecretary().deleteRecord(socket);
190
Coordinator.getCoordinator()
191
.notifyOffline(
192
Coordinator.getCoordinator()
193
.findCaller(socket),
194
chatter.getRoom());
195
this.serverGUI
196
.addText(chatter.getName() + " loged out");// exception
197
// that
198
// will
199
// notify
200
// the
201
// other
202
// users
203
}
204
}
205
socket.close();
206
}
207
catch(IOException ioe)
208
{
209
if(Coordinator.getCoordinator().findCaller(socket) != null)
210
{
211
synchronized(Coordinator.getCoordinator())
212
{
213
Chatter chatter = Secretary.getSecretary().findChatter(
214
socket);
215
Secretary.getSecretary().deleteRecord(socket);
216
Coordinator.getCoordinator()
217
.notifyOffline(
218
Coordinator.getCoordinator()
219
.findCaller(socket),
220
chatter.getRoom());
221
this.serverGUI
222
.addText(chatter.getName() + " loged out");// exception
223
}
224
}
225
socket.close();
226
}
227
}
228
catch(IOException ioe)
229
{
230
}
231
}
232
}
233

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
