服务端
package socket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Scanner;
import socket.Client.ServerHandler;
public class Server {
private Socket socket;
Scanner sca=new Scanner(System.in);
//定义断口,定义集合存放所有客户端的输出流
private ServerSocket server;
private Collection<PrintWriter> collection=new ArrayList<PrintWriter>();
public Server() {
try {
System.out.println("正在启动服务端....");
server=new ServerSocket(9999);
System.out.println("服务端启动完毕!");
} catch (Exception e) {
e.printStackTrace();
}
}
public void start() {
try {
//多次调用accept方法可以接受多个客户端的连接;
while(true) {
System.out.println("正在等待客户端连接....");
Socket socket=server.accept();
System.out.println("一个客户端连接了!");
//创建一个线程来处理客户端的交互,与主线程并发运行
ClientHandler handler=new ClientHandler(socket);
Thread t=new Thread(handler);
t.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server s=new Server();
s.start();
}
//该线程负责与客户端交互
private class ClientHandler implements Runnable{
private Socket socket;
//远端计算机地址信息
private String host;
public ClientHandler(Socket socket) {
this.socket=socket;
//通过Scoket获取远端计算机的地址信息的字符串形式
host=socket.getInetAddress().getHostAddress();
}
public void run() {
PrintWriter pw=null;
try {
//获取输入流
InputStream 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);
//将输出流添加到集合中
synchronized (collection) {
collection.add(pw);
}
System.out.println(host+"上线了,当前在线"+collection.size()+"人");
//读取客户端发来的发信息
String message=null;
while((message=br.readLine())!=null) {
System.out.println(host+"说:"+message);
synchronized (collection) {
//遍历集合,给所有客户端发消息
for(PrintWriter p:collection) {
p.println(host+"说:"+message);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
synchronized (collection) {
//客户端断开连接后,在集合删除
collection.remove(pw);
}
System.out.println(host+"下线了,当前在线"+collection.size()+"人");
//通过Socket的close关闭来释放资源
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
客户端
package socket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class Client {
private Socket socket;
Scanner sca=new Scanner(System.in);
public Client() {
try {
System.out.println("与服务端建立连接.....");
socket=new Socket("localhost",9999);
System.out.println("成功建立连接!");
} catch (Exception e) {
e.printStackTrace();
}
}
public void write() {
try {
//线程
ServerHandler handler=new ServerHandler();
Thread t=new Thread(handler);
t.start();
//写入
OutputStream os=socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os,"UTF-8");
BufferedWriter bw=new BufferedWriter(osw);
PrintWriter pw=new PrintWriter(bw,true);
while(true) {
pw.println(sca.nextLine());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client c=new Client();
c.write();
}
public class ServerHandler implements Runnable{
public void run() {
try {
//读出
InputStream is=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is,"UTF-8");
BufferedReader br=new BufferedReader(isr);
String message=null;
while((message=br.readLine())!=null) {
System.out.println(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}