Java Socket 编程——多线程网络聊天程序

 首先,进行服务端的编程,作为服务端,编程主要按下面几个步骤进行:

    // 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(""1050, 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(400300);
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


    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值