`

通信多人聊天基础

    博客分类:
  • JAVA
 
阅读更多

                                                         多个客户端实现多人聊天

           前面已经讲过一个客户端与一个服务器相连的情况,然而发现再加入一个客户端的时候,程序不能如期

运行,这是因为当你创建的只是一个客户端,另一个客户端是不能连入,简而言之就是服务器只把门牌号给了一个上访者,这时就要不断创建客户端,如下:

while(true){
     //等待客户端访问
     Socket socket=host.accept();
     System.out.println("有人访问了");
     //把跟客户端交流的事情交给线程处理
     ServerThread st = new ServerThread(socket);
     //开启线程     st.start();

    }

同一时间处理多个实物,就必须要用到线程了

这时创建一个ServerThread来继承线程类处理发送来的客户端对象

为了一会得到各个客户端对象,我们在线程里面建立对象来存储

private static ArrayList<ServerThread> list=new ArrayList<ServerThread>();
 private OutputStream output;
 private Socket socket;
 private String name;

一下是完整代码:

public class Server {
	
	public void setup(int port){
		
			try {
				//创建服务器
				ServerSocket host=new ServerSocket(port);
				System.out.println("通信端口"+port+"成功开启");
				while(true){
					//等待客户端访问
					Socket socket=host.accept();
					System.out.println("有人访问了");
					//把跟客户端交流的事情交给线程处理
					ServerThread st = new ServerThread(socket);
					//开启线程					st.start();

				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		
	}
	public static void main(String[] args){
		new Server().setup(8888);
	}

}

 

这是服务器类,具体过程参见博客通信初步

下面是线程处理类:

public class ServerThread extends Thread{
	private static ArrayList<ServerThread> list=new ArrayList<ServerThread>();
	private OutputStream output;
	private Socket socket;
	private String name;
	public ServerThread(Socket socket){
		this.socket=socket;
		list.add(this);
	}
	//发送给客户端的信息
	public void sendMessage(String msg){
		try {
			output.write(msg.getBytes("GBK"));
		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void run(){
		try {
			InputStream input=socket.getInputStream();
			output=socket.getOutputStream();
			String str="请输入你的昵称:";
			sendMessage(str);
			//用户名为第一次输入的名字及括号内包括其服务器地址与客户端地址
			name=readLine(input)+"("+socket.getInetAddress().getHostAddress()+")";
			while(true){
				String chat=readLine(input);
				if(chat.equals("再见")){
					System.out.println(name+"下线了");
					break;
				}
				System.out.println(name+"说:"+chat);
				//群发消息的功能
				for(int i=0;i<list.size();i++){
					ServerThread st=list.get(i);
					//if(this==st)
						//continue;
					//将显示咋服务器上的文字转发到其他客户端上,实现群聊的功能
					String chaton=name+"说:"+chat+"\r\n";
					st.sendMessage(chaton);
					
				}
			}
            //下线break到这里,关闭客户端端口,断开连接,同时移除客户端对象
			socket.close();
			list.remove(this);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	public String readLine(InputStream input) throws IOException{
		ByteArrayOutputStream baos=new ByteArrayOutputStream();
		while(true){
			int n=input.read();
			if(n=='\r'){
				continue;
			}
			if(n=='\n'){
				break;
			}
			baos.write(n);
		}
		byte[] bytes=baos.toByteArray();
		String chat=new String(bytes,"GBK");
		return chat;
		
		
	}

}

 

实现的效果如下图,已经可以处理多人通信了:



 再多加几个人聊天效果一样,接下啦,就可以做个较为漂亮的聊天软件了,例如QQ,一起动手吧

 

 

  • 大小: 24.1 KB
2
1
分享到:
评论
1 楼 rainsilence 2014-10-20  
1.用ByteArrayOutputStream 的意义何在,而且用了也没有close
2.没有心跳测试
3.bio多线程的模型虽然简单,但是服务器负担很大
4.所有的close都没有放入finally里,万一try块中报错,stream全都不会关闭,从而造成内存泄露
5.static ArrayList如果不考虑负载均衡,只在局域网内用,那还可以

相关推荐

Global site tag (gtag.js) - Google Analytics