// 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进行编程,将其改造成多线程聊天程序,可以同时进行多客户端的连接与发送信息。
代码如下:
//
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(Client58
.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(Client139
.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(skt205
.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
else333
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
}
本文详细介绍了一个基于Java的网络聊天程序实现方法,包括服务端和客户端的编程步骤,并通过多线程实现了多客户端的同时连接和信息交互。

被折叠的 条评论
为什么被折叠?



