023.java_聊天室

分解步骤:

1.服务器接收客户端的信息(BufferedReader  socket.getInputStream())

2.服务器接收并返回客户端的信息(PrintWriter out  socket.getOutputStream()    out.println(msg);)

3.客户端通过键盘持续的发送消息并接收服务器端返回的消息(客户端套接字输出流监听键盘,并将键盘输入的内容输出到服务器,然后服务器接收客户端输入的内容并输出到客户端,然后客户端读取服务器输入的内容并输出(要在客户端定义两个线程,一个负责向客户端发送消息,一个接收从客户端发来的消息))

4.服务器端同时处理多个客户端的请求(在服务器端通过死循环,每当有新客户端运行连接进来,就启动一个线程)

5.让聊天室的人可以看到彼此的信息(把用户的输出流加入到一个集合,遍历这个集合的输出流)

Server

import java.net.*;
import java.io.*;
import java.util.*;
public class Server {
	private static final List<PrintWriter> list = new ArrayList<>();
	private static final Object lock=new Object();//定义一把锁,限制对集合的操作
	public static void start() throws IOException{
		ServerSocket socket=new ServerSocket(9015);
		System.out.println("服务器开启");
		while(true){                      //每当有用户进来
			Socket s=socket.accept();
			System.out.println(">>>有新的客户端连接进来");
			new Thread( new Runnable() {
				public void run() {
					// TODO Auto-generated method stub
					try {
						BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));//读取客户端信息
						PrintWriter out=new PrintWriter(new OutputStreamWriter(s.getOutputStream()),true);//向客户端发送信息
						synchronized (lock) {
							list.add(out);//将用户的输出流放在集合
						}
							String msg=null;
							
							/*有用户中途退出/会抛异常*/
//							while(null!=(msg=br.readLine())){
//								for(PrintWriter bw:list){
//									bw.println(msg);
//									bw.flush();
//								}
//							}
							
							synchronized (lock) {
								while(null!=(msg=br.readLine())){
								//通过迭代器遍历,有用户退出(抛异常)就移出他
								Iterator<PrintWriter>iterator=list.iterator();
								while(iterator.hasNext()){
									PrintWriter pw=iterator.next();
									try{
										pw.println(msg);
										pw.flush();
									}catch(Exception e){
										iterator.remove();
									}
								}
							}
						}
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} finally {
						if(null!=s){
							try {
								s.close();
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						if(null!=socket){
							try {
								socket.close();
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					}
				}
			}).start();
		}
		
		
	}
	public static void main(String[] args) throws IOException {
		Server.start();
	}
}

Client

import java.net.*;
import java.io.*;
public class Client {

	public static void start() throws UnknownHostException, IOException {
		Socket s = new Socket("127.0.0.1",9015);//套接字 用来连接服务器;
		
		//监听键盘,向服务器端发送消息
		new Thread(new Runnable() {
			public void run() {
				try {
					BufferedReader br=new BufferedReader(new InputStreamReader(System.in));//监听键盘
					PrintWriter pw=new PrintWriter(new OutputStreamWriter(s.getOutputStream()),true);//自动刷新  向服务器发送信息
					String msg=null;
					while(null!=(msg=br.readLine())){
//						System.out.println(msg);//输出键盘输入的信息
						pw.println(msg);//向服务器发送消息
					}
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} finally{
					if(null!=s){
						try {
							s.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}
		}, "client send").start();
		
		//读取服务器端返回的消息
		new Thread(new Runnable() {
			public void run() {
				BufferedReader in;
				try {
					in = new BufferedReader(new InputStreamReader(s.getInputStream()));
					String data=null;
					while(null!=(data=in.readLine())){
						System.out.println(">>>"+data);
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}, "client receive").start();
	}
	public static void main(String[] args) throws UnknownHostException, IOException {
		// TODO Auto-generated method stub
		Client.start();
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值