服务端代码
public class Server2dl {
private ServerSocket severSocket;
//存储所有客户端的输出流
private Map<String,PrintWriter> allout;
Server2dl(){
try {
//创建服务端的ServerSocket对象
severSocket=new ServerSocket(8087);
allout=new HashMap<String,PrintWriter>();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//创建内部类,继承runnable的形式创建线程
private class clientHandler implements Runnable{
private Socket socket;
String user;
clientHandler(Socket socket){
this.socket=socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
//获取向该客户端发送信息的输出流,并且将该流包装成PrintWriter之后
//放入集合中,如果客户掉线,集合中对应的输出流从集合中删除
PrintWriter pw=null;
InputStream is;
PrintWriter p1=null;
try {
//获取outputStream对象 获取socket中的输出流
OutputStream os=socket.getOutputStream();
//缓冲字符输出流
OutputStreamWriter osw=new OutputStreamWriter(os,"utf-8");
pw=new PrintWriter(osw,true);
//将用户信息放入集合当中
//在获取到了客户端发送过来的信息后遍历集合allout
//将获取到的信息写入该集合中每一个输出流中,从而将信息发送给所有的客户端
//声明该线程被创建后要执行的任务
is = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
String message=null;
//readLine只有在数据流发生异常,或者另一端被close()的时候返回null值
while((message=br.readLine()) != null) {
//遍历所有的输出流,将该客户端发送的信息转发给所有的用户
String kf=message.substring(message.lastIndexOf("对")+1, message.lastIndexOf("说:"));
//System.out.println(kf);
user=message.substring(message.lastIndexOf("户")+1, message.lastIndexOf("对"));
allout.put(user, pw);
//System.out.println(allout);
//System.out.println(kf);
if(allout.get(kf)==null) {
pw.println("该用户还未连接");
}
if(allout.get(kf)!=null) {
p1=allout.get(kf);
pw.println(message);
p1.println(message);
}
System.out.println(message);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//当客户掉线的时候,要将输出流从集合删除
allout.remove(user);
if(socket!=null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public void start() {
System.out.println("等待客户端的连接");
//监听客户端的连接
Socket socket;
try {
while(true) {
//连接客户端的socket的对象
socket = severSocket.accept();
System.out.println("客户端已连接");
//启动线程来完成针对该客户端的交互 因为accept()有阻塞的功能
//accept()方法会产生阻塞,直到某个Socket连接,并返回请求连接的socket
//所以程序在 多人访问时必须用线程并发执行
Thread t=new Thread(new clientHandler(socket));
t.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Server2dl server=new Server2dl();
server.start();
}
}
客户端代码:
//客户端应用程序
//第一步:实现向服务器发送一条信息
public class Client2dl {
//创建Socket实例
private Socket socket;
public Client2dl() {
try {
//创建socket连接
socket=new Socket("localhost",8087);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//客户端工作方法
public void start() {
Scanner sc=null;
try {
//接收服务器端的信息并且启动线程
ServerHander handler=new ServerHander();
Thread r=new Thread(handler);
r.start();
//获取outputStream对象 获取socket中的输出流
OutputStream os=socket.getOutputStream();
//缓冲字符输出流
OutputStreamWriter osw=new OutputStreamWriter(os,"utf-8");
PrintWriter out=new PrintWriter(osw,true);
//创建Scanner类读取用户输入内容
System.out.println("请输入你的用户名:");
sc=new Scanner(System.in);
String user=sc.nextLine();
System.out.println("请输入你想和谁聊:");
sc=new Scanner(System.in);
String say=sc.nextLine();
System.out.println("输入您的聊天内容");
sc=new Scanner(System.in);
//将信息 发送给服务器
while(true) {
out.println("用户"+user+"对"+say+"说:"+sc.nextLine());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
if(socket!=null) {
socket.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class ServerHander implements Runnable{
@Override
public void run() {
InputStream is;
// TODO Auto-generated method stub
//接收服务端发送的信息
//循环接收并显示
try {
is = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
while(true) {
System.out.println(br.readLine());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//创建main方法
public static void main(String[] args) {
Client2dl c=new Client2dl();
c.start();
}
}
PS:先运行服务端,后运行客户端.