您的位置:首页 > 编程语言 > Java开发

java类似QQ的聊天室程序的实现(下)(服务器端程序)

2016-05-10 19:48 621 查看
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
* 聊天室客户端
* @author~~
*/

public class Server {
/*
* java.net.ServerScoket
* 运行在服务端的ServerSocket有两个作用
* 1:申请服务端口(客户端通过该端口与服务端建立链接)
* 2 监听端口:一旦客户通过该端口链接后,会创建一个Scoket实例与该客户进行通讯
*/
private ServerSocket server;
// 保存所有客户端的流
private List<PrintWriter> allOut;
public Server() throws IOException{
/*
*  创建ServerScoket同时需要申请服务端口
*  这个端口不能与其他使用TCP协议的应用程序冲突
*  否测 会抛出异常
*
*/
server=new ServerSocket(8088);
allOut =new ArrayList<PrintWriter>();

}
private synchronized void  addOut(PrintWriter pw){
/*
* 将指定的客户端的输出流从共享的集合中删除
* @param pw
*/
allOut.add(pw);
}
private  synchronized void  removeOut(PrintWriter pw){
allOut.remove(pw);
}
/*
* 广播消息 将给定的消息通过遍历共享集合将该消息发送给没有个客户端
*/

private synchronized  void sendMessagage(String message){
for(PrintWriter pw:allOut){
pw.println(message);
}
}
public void start() throws IOException{
while(true){
System.out.println("等待客户端链接...");
/*
* Socket accept()
* serversocket提供了accept方法用来监听打开的服务端口
* 一旦一个客户端通过该端口请求时 就会创建一个socket并返回
* 通过该socket就可以与客户端进行交互了
* 该方法是一个阻塞方法
* 直到客户端连接才会有返回值
*/
Socket socket=server.accept();
ClientHandler hander=new ClientHandler(socket);
Thread t=new Thread(hander);
t.start();
}

}
public static void main(String[] args) {
try{
Server server=new Server();
server.start();
}catch(Exception  e){
e.printStackTrace();
}
}
/*
* 该类十一个线程的任务,负责与指定客户端进行交互
*
*/

private class ClientHandler implements Runnable{
/*
* 当前线程需要需要处理的针对客户端socket
*/
private Socket socket;
private String host;

public ClientHandler(Socket socket){
this.socket=socket;
InetAddress address=socket.getInetAddress();
host=address.getHostAddress();
}
@Override
public void run() {
PrintWriter pw=null;
try{
//sendMessagage(host+" 上线了"+allOut.size()+"人在线");
//System.out.println(host+"上线了!");
//创建输出流 用来将消息发送至客户端
OutputStream out=socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(out,"UTF-8");
//PrintWriter pw=new PrintWriter(osw,true);
pw=new PrintWriter(osw,true);
//将该客户端的输出流存入共享集合
addOut(pw);
sendMessagage(host+" 上线了"+allOut.size()+"人在线");
/*
* 	InputStream getInputStream()
* socket 提供的该方法可以获取一个输入流,
* 通过该输入流可以读取远端计算机发送过来的数据
*/
//Thread thead=Thread.currentThread();
InputStream in=socket.getInputStream();
InputStreamReader inr=new InputStreamReader(in,"UTF-8");
BufferedReader buf=new BufferedReader(inr);
String message=null;
while((message=buf.readLine())!=null){
/*
* 使用br.readLine方法读取远端计算机发送过来的数据时,由于客户端操作系统不同,当断开连接时这里的反应也不相同。
* 当linux的客户端断开连接:会返回null
* 当windows客户端断开时:会抛出异常
*/
//	System.out.println(host+"说:"+message);
//	pw.println(host+"说:"+message);
sendMessagage(host+" 说 :"+message);
//sendMessagage(host+)

}

}catch(IOException e){
e.printStackTrace();
} finally{
//客户端断开链接处理
//将噶客户端的输出流从从共享集合中删除
removeOut(pw);
//System.out.println(host+"下线了");
sendMessagage(host+"下线了"+"还剩多少人在线"+allOut.size());
try{
socket.close();
}catch(IOException  e){
e.printStackTrace();
}
}
}
}}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: