首先,进行服务端的编程,作为服务端,编程主要按下面几个步骤进行:
// 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
}