首先,进行服务端的编程,作为服务端,编程主要按下面几个步骤进行:
// 1. 创建socket
ServerSocket ss = new ServerSocket(PortNumber);
Socket s = ss.accept(); //监听器,产生阻塞,直到有连接才停止阻塞。
// 2. 打开输入流、输出流
OutputStream os = s.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
InputStream is = s.getInputStream();
// 3. 根据一定的协议读写数据
// 服务器 --> 客户
//os.write("Hello,I am Server!".getBytes());
bos.write("Hello,I am Server!".getBytes());
bos.flush(); //注意!!
// 服务器 <-- 客户
byte[] buf = new byte[100];
int len = is.read(buf);
System.out.println(new String(buf, 0, len));
// 4. 关系流和Socket
//os.close();
bos.close();
is.close();
s.close();
ss.close();
作为客户端则分为下面几个步骤,其实和服务端差不多,只是少了用ServerSocket进行监听。
// 1. 创建socket
Socket s = new Socket(InetAddress.getByName("localhost"),
PortNumber);
// 2. 打开输入流、输出流
OutputStream os = s.getOutputStream();
InputStream is = s.getInputStream();
// 3. 根据一定的协议读写数据
// 服务器 --> 客户
byte[] buf = new byte[100];
int len = is.read(buf);
System.out.println(new String(buf, 0, len));
// 服务器 <-- 客户
os.write("Hello,I am Client!".getBytes());
// 4. 关系流和Socket
os.close();
is.close();
s.close();
上面这些只是一个单线程的服务端->客户端的程序,只能进行一次通讯,多次通讯将被告知无法连接。
这时,我们就需要用到进程Thread进行编程,将其改造成多线程聊天程序,可以同时进行多客户端的连接与发送信息。
代码如下:
1
//Server.java
2
3
import java.awt.*;
4
import java.net.*;
5
import java.io.*;
6
7
public class Server extends Thread
{
8
ServerSocket skt;
9
10
Socket Client[]=new Socket[10];;
11
Socket Client1=null;
12
13
int i = 0;
14
15
TextArea in;
16
17
int port,k=0,l=0;
18
19
//BufferedReader theInputStream;
20
21
PrintStream theOutputStream;
22
23
//String readin;
24
25
Face chat;
26
27
public Server(int port, Face chat)
{
28
try
{
29
this.port = port;
30
skt = new ServerSocket(port);
31
this.chat = chat;
32
} catch (IOException e)
{
33
chat.ta.append(e.toString());
34
}
35
}
36
37
public void run()
{
38
39
chat.ta.append("等待连线
");
40
41
while (true)
{
42
//System.out.print(""+i+"\n");
43
try
{
44
45
46
Client[k] = skt.accept(); /**//* 接收客户连接 */
47
48
//当有客户端连接时就新建一个子线程
49
50
51
if (i < 2)
{
52
ServerThread server[] = new ServerThread[10];
53
server[k]= new ServerThread(Client[k], this.chat, i);
54
l=server.length;
55
server[k].start();
56
chat.ta.append("客户端" + Client[k].getInetAddress() + "已连线\n");
57
/**//*theInputStream = new BufferedReader(new InputStreamReader(Client
58
.getInputStream()));*/
59
//for(int j=0;j<server.length;j++)
60
theOutputStream = new PrintStream(server[k].getClient().getOutputStream());
61
i = server[k].getI();
62
k++;
63
} else
{
64
//theOutputStream = new PrintStream(null);
65
}
66
67
} catch (SocketException e)
{
68
//chat.ta.append("连线中断!\n");
69
70
//chat.clientBtn.setEnabled(true);
71
//chat.serverBtn.setEnabled(true);
72
//chat.tfaddress.setEnabled(true);
73
//chat.tfport.setEnabled(true);
74
//try {
75
76
//skt.close();
77
//Client.close();
78
//} catch (IOException err) {
79
// chat.ta.append(err.toString());
80
//}
81
} catch (IOException e)
{
82
chat.ta.append(e.toString());
83
}
84
}
85
86
}
87
88
public void dataout(String data)
{
89
//for(int j=0;j<l;j++)
90
theOutputStream.println(data);
91
}
92
}
93
94
class ServerThread extends Thread
{
95
ServerSocket skt;
96
97
Socket Client;
98
99
TextArea in;
100
101
int port;
102
103
int i;
104
105
BufferedReader theInputStream;
106
107
PrintStream theOutputStream;
108
109
String readin;
110
111
Face chat;
112
113
//服务端子线程
114
115
public ServerThread(Socket s, Face chat, int i)
{
116
this.i = ++i;
117
Client = s;
118
//this.port = port;
119
//skt = new ServerSocket(port);
120
this.chat = chat;
121
122
}
123
124
public int getI()
{
125
return this.i;
126
}
127
public Socket getClient()
{
128
return this.Client;
129
}
130
public void run()
{
131
132
//chat.ta.append("等待连线
");
133
134
try
{
135
//Client = skt.accept(); /* 接收客户连接 */
136
137
//chat.ta.append("客户端" + Client.getInetAddress() + "已连线\n");
138
theInputStream = new BufferedReader(new InputStreamReader(Client
139
.getInputStream()));
140
theOutputStream = new PrintStream(Client.getOutputStream());
141
142
while (true)
{
143
readin = theInputStream.readLine();
144
chat.ta.append(readin + "\n");
145
}
146
147
} catch (SocketException e)
{
148
chat.ta.append("连线中断!\n");
149
150
chat.clientBtn.setEnabled(true);
151
chat.serverBtn.setEnabled(true);
152
chat.tfaddress.setEnabled(true);
153
chat.tfport.setEnabled(true);
154
try
{
155
i--;
156
skt.close();
157
Client.close();
158
} catch (IOException err)
{
159
chat.ta.append(err.toString());
160
}
161
} catch (IOException e)
{
162
chat.ta.append(e.toString());
163
}
164
}
165
166
public void dataout(String data)
{
167
theOutputStream.println(data);
168
}
169
}
170
171
//Client.java
172
173
import java.net.*;
174
import java.io.*;
175
import javax.swing.Timer;
176
class Client extends Thread
{
177
Socket skt;
178
InetAddress host;
179
int port;
180
181
BufferedReader theInputStream;
182
PrintStream theOutputStream;
183
String readin;
184
185
Face chat;
186
187
public Client(String ip, int p, Face chat)
{
188
try
{
189
host = InetAddress.getByName(ip);
190
port = p;
191
this.chat = chat;
192
} catch (IOException e)
{
193
chat.ta.append(e.toString());
194
}
195
}
196
197
public void run()
{
198
try
{
199
chat.ta.append("尝试连线
");
200
201
skt = new Socket(host, port);
202
chat.ta.append("连线成功\n");
203
204
theInputStream = new BufferedReader(new InputStreamReader(skt
205
.getInputStream()));
206
207
theOutputStream = new PrintStream(skt.getOutputStream());
208
//Timer myTimer = new Timer();
209
while (true)
{
210
readin = theInputStream.readLine();
211
chat.ta.append(readin + "\n");
212
}
213
} catch (SocketException e)
{
214
chat.ta.append("连线中断!\n");
215
chat.clientBtn.setEnabled(true);
216
chat.serverBtn.setEnabled(true);
217
chat.tfaddress.setEnabled(true);
218
chat.tfport.setEnabled(true);
219
try
{
220
skt.close();
221
} catch (IOException err)
{
222
chat.ta.append(err.toString());
223
}
224
} catch (IOException e)
{
225
chat.ta.append(e.toString());
226
}
227
}
228
229
public void dataout(String data)
{
230
theOutputStream.println(data);
231
}
232
}
233
234
//软件界面,进行按键监听调用。
235
//face.java
236
237
import java.awt.*;
238
import java.awt.event.*;
239
240
public class Face extends Frame
{
241
/** *//**
242
*
243
*/
244
private static final long serialVersionUID = 1L;
245
Button clientBtn, serverBtn;
246
TextArea ta;
247
TextField tfaddress, tfport, tftype;
248
int port;
249
Client client;
250
Server server;
251
boolean iamserver;
252
static Face frm;
253
254
public Face()
{
255
clientBtn = new Button("客户端");
256
serverBtn = new Button("服务器");
257
ta = new TextArea("", 10, 50, TextArea.SCROLLBARS_BOTH);
258
tfaddress = new TextField("192.168.1.104", 20);
259
tfport = new TextField("2000");
260
tftype = new TextField(50);
261
262
tftype.addKeyListener(new TFListener());
263
ta.setEditable(false);
264
265
setLayout(new FlowLayout());
266
add(tfaddress);
267
add(tfport);
268
add(clientBtn);
269
add(serverBtn);
270
add(ta);
271
add(tftype);
272
setSize(400, 300);
273
setTitle("我的聊天室");
274
this.setVisible(true);
275
276
clientBtn.addActionListener(new ActionListener()
{
277
public void actionPerformed(ActionEvent e)
{
278
279
port = Integer.parseInt(tfport.getText());
280
281
client = new Client(tfaddress.getText(), port, frm);
282
283
client.start();
284
285
tfaddress.setEnabled(false);
286
tfport.setEnabled(false);
287
serverBtn.setEnabled(false);
288
clientBtn.setEnabled(false);
289
}
290
});
291
292
serverBtn.addActionListener(new ActionListener()
{
293
public void actionPerformed(ActionEvent e)
{
294
295
port = Integer.parseInt(tfport.getText());
296
297
server = new Server(port, frm);
298
299
server.start();
300
301
iamserver = true;
302
tfaddress.setText("成为服务器");
303
304
tfaddress.setEnabled(false);
305
tfport.setEnabled(false);
306
serverBtn.setEnabled(false);
307
clientBtn.setEnabled(false);
308
}
309
});
310
311
addWindowListener(new WindowAdapter()
{
312
public void windowClosing(WindowEvent e)
{
313
System.exit(0);
314
}
315
});
316
317
}
318
319
public static void main(String args[])
{
320
frm = new Face();
321
}
322
323
private class TFListener implements KeyListener
{
324
public void keyPressed(KeyEvent e)
{
325
326
if (e.getKeyCode() == KeyEvent.VK_ENTER)
{
327
328
ta.append(">" + tftype.getText() + "\n");
329
330
if (iamserver)
331
server.dataout(tftype.getText());
332
else
333
client.dataout(tftype.getText());
334
335
tftype.setText("");
336
}
337
}
338
339
public void keyTyped(KeyEvent e)
{
340
}
341
342
public void keyReleased(KeyEvent e)
{
343
}
344
}
345
}
这个程序我限制了连接数,大家可以根据自己的需要进行修改。