博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于GUI的简单聊天室03
阅读量:4624 次
发布时间:2019-06-09

本文共 4472 字,大约阅读时间需要 14 分钟。

上一版本,客户端关闭后会出现“socket close”异常问题,这个版本用捕捉异常来解决,实际上只是把异常输出的语句改为用户退出之类,并没真正解决

服务器类

package Chat03;/** * 相比01,加进了线程内部类,解决多个客户端连接时,服务器无法全部响应的问题。 * @author Administrator * */import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.EOFException;import java.io.IOException;import java.net.BindException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.List;public class ChatSever03 {    // 布尔类型变量表示服务器是否开着    boolean started = false;        ServerSocket ss = null;    List
clients = new ArrayList
(); public static void main(String[] args) { new ChatSever03().start(); } public void start() { try { // 建立服务端,8888为端口号 ss = new ServerSocket(8888); started = true; } catch (BindException e) { System.out.println("Socket has been used !"); System.out.println("请重启服务器 !"); System.exit(0); }catch (IOException e) { e.printStackTrace(); } // 服务器开启后,started变为true try { // 接受客户端的连接 while (started) { Socket s = ss.accept(); //构造Client对象 Client c = new Client(s); clients.add(c); System.out.println("一个客户连接"); //启动线程 new Thread(c).start(); } } catch (Exception e) { e.printStackTrace(); } finally { try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 建立线程内部类 */ class Client implements Runnable{ //要保有自己的Socket属性 private Socket s = null; //自己的数据输入流 private DataInputStream dis = null; private DataOutputStream dos = null; private boolean bConnected = false ; //采用构造方法,把Socket属性传进来 public Client(Socket s) { //赋值给s this.s = s ; //将dis初始化 try { dis = new DataInputStream(s.getInputStream()); dos = new DataOutputStream(s.getOutputStream()); //连接成功后,bConnected 变为true bConnected = true ; } catch (IOException e) { e.printStackTrace(); } } /** * 发送信息的方法 */ public void send(String str) { try { dos.writeUTF(str);System.out.println(str); } catch (IOException e) { clients.remove(this); System.out.println("对方退出了"); //e.printStackTrace(); } } @Override public void run() { try { //while循环范围过大, 导致过一直报错; while (bConnected) { String str = dis.readUTF ();//System.out.println(str); //发送信息 for(int i = 0;i < clients.size(); i++) { Client c = clients.get(i); c.send(str);//System.out.println(str); } /*利用迭代器 for(Iterator it = clients.iterator();it.hasNext();) { Client c = it.next(); c.send(str); } */ /*利用迭代器第二版本 Iterator
it = clients.iterator(); while(it.hasNext()) { Client c = it.next(); c.send(str); } */ } }catch (EOFException e) { System.out.println("Client Close !"); }catch (IOException e) { e.printStackTrace(); }finally { try { if(dis != null) dis.close(); //再设置dis = null; if(dos != null) dis.close(); if(s != null) s.close(); } catch (IOException e) { e.printStackTrace(); } } } }}

 

转载于:https://www.cnblogs.com/happyeven/p/10765877.html

你可能感兴趣的文章
Luogu4069 SDOI2016 游戏 树链剖分、李超线段树
查看>>
Java的内部类真的那么难以理解?
查看>>
一文搞懂Java环境,轻松实现Hello World!
查看>>
hash实现锚点平滑滚动定位
查看>>
也谈智能手机游戏开发中的分辨率自适应问题
查看>>
关于 IOS 发布的点点滴滴记录(一)
查看>>
《EMCAScript6入门》读书笔记——14.Promise对象
查看>>
CSS——水平/垂直居中
查看>>
Eclipse连接mysql数据库jdbc下载(图文)
查看>>
Python中Selenium的使用方法
查看>>
三月23日测试Fiddler
查看>>
20171013_数据库新环境后期操作
查看>>
SpringMVC中文件的上传(上传到服务器)和下载问题(二)--------下载
查看>>
Socket & TCP &HTTP
查看>>
osip及eXosip的编译方法
查看>>
Hibernate composite key
查看>>
[CF Round #294 div2] D. A and B and Interesting Substrings 【Map】
查看>>
keepalived+nginx安装配置
查看>>
vue+element-ui实现表格checkbox单选
查看>>
autofac
查看>>