-
Version.1:
目的:实现单个客户与服务器的连接。
服务器:
import java.io.*;
import java.net.*;
/*
在线聊天室:服务器
目的:实现单个客户的聊天过程
*/
public class chat {
public static void main(String[] args) throws IOException {
System.out.println("-----Server-----");
//1、指定端口 使用ServerSocket创建服务器
ServerSocket server = new ServerSocket(8888);
//2、阻塞式等待连接 accept()
Socket client = server.accept();
System.out.println("一个客户端建立了连接");
//3、服务器接收消息
DataInputStream dis = new DataInputStream(new BufferedInputStream(client.getInputStream()));
String str = "null";
while(!str.equals("")){
str = dis.readUTF();
System.out.println(str);
}
//3、释放资源
dis.close();
server.close();
}
}
客户端:
import java.io.*;
import java.net.*;
/*
在线聊天室:客户
目的:实现单个客户的聊天过程
*/
public class client {
public static void main(String[] args) throws IOException {
System.out.println("-----Client-----");
//1、建立连接:使用Socket创建客户端 + 服务器的地址和端口
Socket client = new Socket("localhost",8888);
//2、客户端发送消息
String str = "null";
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
while(!str.equals("")){
str = reader.readLine();
dos.writeUTF(str);
dos.flush();
}
//3、释放资源
dos.close();
client.close();
}
}
-
Version.2:
目的:实现多个客户多次、同时收发消息。
服务器:
import SAMPLE.网络编程.TCP协议.聊天室.utils;
import java.io.*;
import java.net.*;
/*
多人多线程在线聊天室:服务器
目的:实现多个客户可以多次、同时收发消息
*/
public class multiChat {
static String[] person = {"","Kvno","Tom","Jerry","Echo","Eric"};
static int clientNum = 0;
public static void main(String[] args) throws IOException {
System.out.println("-----Server-----");
//1、指定端口 使用ServerSocket创建服务器
ServerSocket server = new ServerSocket(8888);
//2、阻塞式等待连接 accept()
while(clientNum>=0) {
Socket client = server.accept();
System.out.println(person[++clientNum]+"进入聊天室");
new Thread(new Channel(client),person[clientNum]).start();
}
server.close();
}
static class Channel implements Runnable {
private DataInputStream dis;
private DataOutputStream dos;
private Socket client;
private boolean flag;
public Channel(Socket client) {
this.client = client;
try {
dis = new DataInputStream(new BufferedInputStream(client.getInputStream()));
dos = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
flag = true;
} catch (IOException e) {
e.printStackTrace();
System.out.println("-----2-----");
close();
}
}
//接收消息
private String receive() {
String str = "null";
try {
str = dis.readUTF();
} catch (IOException e) {
System.out.println("-----1-----");
flag = false;
if(!str.equals("null"))
close();
}
return str;
}
//发送消息
private void send(String str) {
try {
dos.writeUTF(str);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
System.out.println("-----3-----");
close();
}
return ;
}
//释放资源
private void close() {
this.flag = false;
System.out.println(Thread.currentThread().getName()+"离开聊天室");
utils.close(dis,dos,client);
}
@Override
public void run() {
while(flag) {
String str = receive();
if(!str.equals("")&&!str.equals("null")) {
System.out.println(Thread.currentThread().getName()+":"+str);
send(str);
}else {
flag = false;
}
}
close();
}
}
}
客户端:
import SAMPLE.网络编程.TCP协议.聊天室.*;
import java.io.*;
import java.net.*;
/*
多人多线程在线聊天室:客户端
目的:实现多个客户可以多次、同时收发消息
*/
public class multiClient {
public static void main(String[] args) throws IOException {
System.out.println("-----Client-----");
//1、建立连接:使用Socket创建客户端 + 服务器的地址和端口
Socket client = new Socket("localhost",8888);
//2、客户端发送消息
new Thread(new Send(client)).start();
//3、客户端接收消息
new Thread(new Receive(client)).start();
//4、释放资源
//client.close();
}
}
工具类:
1、封装发送消息:
import java.io.*;
import java.net.*;
/*
多线程封装发送端
*/
public class Send implements Runnable {
private Socket client;
private BufferedReader reader;
private DataOutputStream dos;
private boolean flag;
private String str = "null";
public Send(Socket client) {
this.client = client;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
dos = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
flag = true;
} catch (IOException e) {
System.out.println("-----4-----");
close();
}
}
private void send() {
if(!str.equals("")){
try {
str = reader.readLine();
dos.writeUTF(str);
dos.flush();
} catch (IOException e) {
System.out.println("-----5-----");
close();
}
}else {
flag = false;
}
}
private void close() {
this.flag = false;
utils.close(reader,dos,client);
}
@Override
public void run() {
while(flag){
send();
}
close();
}
}
2、封装接收消息:
import java.io.*;
import java.net.*;
/*
多线程封装接收端
*/
public class Receive implements Runnable {
private Socket client;
private DataInputStream dis;
private boolean flag;
private String str;
public Receive(Socket client) {
this.client = client;
try {
dis = new DataInputStream(new BufferedInputStream(client.getInputStream()));
flag = true;
} catch (IOException e) {
System.out.println("-----6-----");
close();
}
}
private void receive() {
String str = null;
try {
str = dis.readUTF();
if(!str.equals("")){
System.out.println(str);
}else {
flag = false;
}
} catch (IOException e) {
flag = false;
close();
}
}
private void close() {
this.flag = false;
utils.close(dis,client);
}
@Override
public void run() {
while(flag){
receive();
}
close();
}
}
3、封装释放资源:
import java.io.*;
/*
释放资源
*/
public class utils {
public static void close(Closeable... io){
for(Closeable i:io){
if (i!= null) {
try {
i.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
-
Version.3:
目的:实现多个客户可以多次、同时针对群体、私人收发消息。引用了Version.2中的封装方法。
服务器:
import SAMPLE.网络编程.TCP协议.聊天室.*;
import java.io.*;
import java.net.*;
import java.util.concurrent.CopyOnWriteArrayList;
/*
多人多线程在线聊天室:服务器
目的:实现多个客户可以多次、同时收发消息
实现群发、私发消息
*/
public class theChat {
private static CopyOnWriteArrayList<Channel> all = new CopyOnWriteArrayList<>();
private static String[] person = {"","Kvno","Tom","Jerry","Echo","Eric"};
private static int clientNum = 0;
public static void main(String[] args) throws IOException {
System.out.println("-----Server-----");
//1、指定端口 使用ServerSocket创建服务器
ServerSocket server = new ServerSocket(8888);
//2、阻塞式等待连接 accept()
while(clientNum>=0) {
Socket client = server.accept();
System.out.println(person[++clientNum]+"进入聊天室");
Channel c = new Channel(client);
all.add(c);
new Thread(c,person[clientNum]).start();
}
server.close();
}
static class Channel implements Runnable {
private DataInputStream dis;
private DataOutputStream dos;
private Socket client;
private boolean flag;
public Channel(Socket client) {
this.client = client;
try {
dis = new DataInputStream(new BufferedInputStream(client.getInputStream()));
dos = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
flag = true;
} catch (IOException e) {
e.printStackTrace();
System.out.println("-----2-----");
close();
}
}
//接收消息
private String receive() {
String str = "null";
try {
str = dis.readUTF();
} catch (IOException e) {
System.out.println("-----1-----");
flag = false;
if(!str.equals("null"))
close();
}
return str;
}
//发送消息
private void send(String str) {
try {
dos.writeUTF(str);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
System.out.println("-----3-----");
close();
}
return ;
}
//群发/私发消息
private void groupSend(String str) {
if(str.startsWith("@")) {
int idx = str.indexOf(':');
String name = str.substring(1,idx);
String msg = str.substring(idx+1);
for(int i=0;i<5;i++) {
if(person[i+1].equals(name))
all.get(i).send(Thread.currentThread().getName()+"悄悄对你说:"+msg);
}
}else {
for (Channel others : all) {
if (others != this)
others.send(Thread.currentThread().getName() + ":" + str);
}
}
return ;
}
//释放资源
private void close() {
this.flag = false;
System.out.println(Thread.currentThread().getName()+"离开聊天室");
utils.close(dis,dos,client);
all.remove(this);
}
@Override
public void run() {
while(flag) {
String str = receive();
if(!str.equals("")&&!str.equals("null")) {
if(!str.startsWith("@"))
System.out.println(Thread.currentThread().getName()+":"+str);
groupSend(str);
}else {
flag = false;
}
}
close();
}
}
}
客户端:
import SAMPLE.网络编程.TCP协议.聊天室.*;
import java.io.IOException;
import java.net.Socket;
/*
多人多线程在线聊天室:客户端
目的:实现多个客户可以多次、同时收发消息
实现群发、私发消息
*/
public class theClient {
public static void main(String[] args) throws IOException {
System.out.println("-----Client-----");
//1、建立连接:使用Socket创建客户端 + 服务器的地址和端口
Socket client = new Socket("localhost",8888);
//2、客户端发送消息
new Thread(new Send(client)).start();
//3、客户端接收消息
new Thread(new Receive(client)).start();
//4、释放资源
//client.close();
}
}