先运行服务器端再运行客户端
//这是客户端
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.*;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
public class Client {
private Scanner scanner=null;
private Socket socket=null;
private String s="";
public Client() {
try {
System.out.println("客户端启动");
socket=new Socket("localhost",8051);
System.out.println("客户端已启动");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() {
try {
ServerClient serverclient=new ServerClient();
Thread t=new Thread(serverclient);
t.start();
OutputStream os=socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os,"utf-8");
BufferedWriter bw=new BufferedWriter(osw);
PrintWriter pw=new PrintWriter(bw,true);
scanner=new Scanner(System.in);
while(true) {
s=scanner.nextLine();
if(s.equals("over")) break;
pw.println(s);
}
}catch(SocketException e) {
System.out.println("无内容");
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Client c=new Client();
c.start();
}
/*
* 定义一个内部类进行内部的消息处理
*/
class ServerClient implements Runnable{
public void run() {
try {
InputStream is=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
String s;
while((s=br.readLine())!=null) {
System.err.println(s);
}
}catch(SocketException e) {
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//这是服务器端
public class Server1 {
private ServerSocket server=null;
private ClientServer clientserver=null;
private String s="";
public PrintWriter[] allout= {};
public Server1() {
try {
System.out.println("服务器开始启动");
server=new ServerSocket(8051);
System.out.println("服务器已启动");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* 定义一个start方法进行对信息接收及发送的处理
*/
public void start() {
while(true) {
try {
System.out.println("--------------------------------");
System.err.println("服务器准备接收");
Socket socket=server.accept();
System.err.println("服务器开始接收");
System.out.println("---------------------------------");
clientserver=new ClientServer(socket);
Thread t=new Thread(clientserver);
t.start();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch(IOException e) {
e.getStackTrace();
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Server1 s=new Server1();
s.start();
}
class ClientServer implements Runnable{
private Socket socket=null;
private String hostname="";
private String words=null;
public ClientServer(Socket socket) {
this.socket=socket;
this.hostname=socket.getInetAddress().getHostName();
}
@Override
public void run() {
InputStream is;
PrintWriter pw=null ;
try {
/*
* 获得客户端发送过来的输入流
*/
is = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
/*
* 获得服务器要发送到客户端的输出流
*/
OutputStream os=socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os,"utf-8");
BufferedWriter bw=new BufferedWriter(osw);
pw=new PrintWriter(bw,true);
/*
* 这个同步代码块时有新的线程时运行一次的
* 目的时将pw放入allout这个输出流数组中
*/
synchronized(allout) {
//数组扩容
allout=Arrays.copyOf(allout,allout.length+1);
//将当前获得的输出流放入数组中
allout[allout.length-1]=pw;
}
System.out.println(hostname+"上线了当前上线人数"+allout.length);
/*
*
*/
while((words=br.readLine())!="over") {
System.out.println(hostname+"<<"+words+";");
//遍历客户端数组向所有客户端发送信息
synchronized(allout) {
for(int begin=0;begin<allout.length;++begin) {
//除了自己向在线的所有人都发送消息
if(allout[begin]!=pw)
allout[begin].println(hostname+"<<"+words);
}
}
}
}catch(SocketException e) {
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//对已经退出的用户| 数据流 |进行删除
synchronized(allout) {
for(int i=0;i<allout.length;i++) {
if(allout[i]==pw) {
allout[i]=allout[allout.length-1];
allout=Arrays.copyOf(allout, allout.length-1);
break;
}
}
}
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(hostname+"下线了当前上线人数"+allout.length);
}
}
}