目录
聊天室案例
(多线程+网络编程)
服务器
package chatRoom;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CopyOnWriteArrayList;
/*
*在线聊天室:服务器
**/
public class Chat {
private static CopyOnWriteArrayList<Channel> all = new CopyOnWriteArrayList<Channel>();
public static void main(String[] args) throws IOException {
System.out.println("-----Server------");
ServerSocket server = new ServerSocket(8888);
while(true){
Socket client = server.accept(); //三次握手发生在连接这里
System.out.println("一个客户端建立了连接");
Channel c = new Channel(client);
all.add(c); //容器管理所有的客户端成员
new Thread(c).start();
}
}
//被频繁调用的类,定义成静态的就不用每次给他实例化了,
static class Channel implements Runnable{
private Socket client;
private DataInputStream dis;
private DataOutputStream dos;
private boolean isRunning= true;
private String name;
public Channel(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
System.out.println("构造客户端出问题了");
myClose(dis,dos,client);
}
}
private String receive(){
String msg = "" ;
try {
msg = dis.readUTF();
} catch (IOException e) {
System.out.println("接收信息出问题了");
myClose(dis,dos,client);
}
return msg;
}
private void send(String msg,String name){
try {
dos.writeUTF(name);
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
System.out.println("发送信息出问题了");
myClose(dis,dos,client);
}
}
private void sendOthers(String msg,String name){
for(Channel other:all){
if(other==this){//自己
continue;
}
other.send(msg,name);
}
}
private void myClose(Closeable... targets){
for(Closeable target:targets){
try{
if(null!=target){
target.close();
this.isRunning = false;
}
}catch (Exception e){
e.printStackTrace();
}
}
}
@Override
public void run() {
while(isRunning){
String name = receive();
String msg = receive();
if(!msg.equals("")){
//send(msg);
sendOthers(msg,name);
}
}
}
}
}
客户端
package chatRoom;
import java.io.*;
import java.net.Socket;
/*
*在线聊天室:客户端
**/
public class Client {
public static void main(String[] args) throws IOException {
System.out.println("-----Client------");
System.out.println("请输入用户名: ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String name = br.readLine();
Socket client = new Socket("localhost",8888);
System.out.println("输入成功");
new Thread(new Client3.Send(client,name)).start();
new Thread(new Client3.Receive(client)).start();
}
static class Receive implements Runnable{
private DataInputStream dis;
private String msg;
private Socket client;
private boolean isRunning=true;
private String name;
public Receive(Socket client){
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
System.out.println("客户端接受构造异常");
myClose(dis,client);
this.isRunning = false;
}
}
@Override
public void run() {
while(isRunning){
try {
this.name = dis.readUTF();
msg = dis.readUTF();
if(!msg.equals("")){
System.out.println(this.name+"说: "+msg);
}
} catch (IOException e) {
System.out.println("客户端接受信息异常");
this.isRunning = false;
}
}
}
}
static class Send implements Runnable{
private BufferedReader console;
private DataOutputStream dos;
private Socket client;
private boolean isRunning=true;
private String name;
public Send(Socket client,String name){
this.client = client;
this.name = name;
console= new BufferedReader(new InputStreamReader(System.in));
try {
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
System.out.println("客户端发送构造异常");
myClose(dos,client);
this.isRunning = false;
}
}
@Override
public void run() {
while(isRunning){
String msg;
try {
msg = console.readLine();
dos.writeUTF(name);
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
System.out.println("客户端发送信息异常");
myClose(dos,client);
this.isRunning = false;
}
}
}
}
public static void myClose(Closeable... targets){
for(Closeable target:targets){
try{
if(null!=target){
target.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
1. 可以运行多个客户端程序,实现群聊。
2. 私聊,以name作为判断if语句。启动私聊也需要一个判断,可以用@标识符。