客户端:
package com.chen.Web.tcp.chat01;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 客户端
* @author Administrator
*
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入这个客户端的名字");
String name = br.readLine();
// 创建客户端,连接本机的9999端口
Socket client = new Socket("localhost", 9999);
new Thread(new Send_Thread(client, name)).start();
new Thread(new Receive_Thread(client)).start();
}
}
服务器端:
package com.chen.Web.tcp.chat01;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* 服务器端
* @author Administrator
*
*/
public class Server {
List<MyChannel> continer = new ArrayList<MyChannel>();
public static void main(String[] args) throws IOException {
new Server().start();
}
/**
* 由于内部类的原因,创建一个启动方法
* @throws IOException
*/
public void start() throws IOException {
// 创建服务端 ServerSocket 加服务器端口
ServerSocket server = new ServerSocket(9999);
// 阻塞式监听接口
while(true) {
Socket client = server.accept();
MyChannel channel = new MyChannel(client);
continer.add(channel);
new Thread(channel).start();
}
}
/**
* 一个客户端,一条通道
* @author Administrator
*
*/
private class MyChannel implements Runnable {
// 输出流
private DataInputStream is;
// 输入流
private DataOutputStream os;
// 标识线程是否运转
private boolean isRunning = true;
private String name;
public MyChannel(Socket client) {
try {
is = new DataInputStream(client.getInputStream());
os = new DataOutputStream(client.getOutputStream());
this.name = is.readUTF();
send("欢迎您进入聊天室");
sendOthers(this.name+"进入聊天室", true);
System.out.println(this.name+"进入聊天室");
} catch (IOException e) {
this.isRunning = false;
IoUtils.closeAll(os, is);
e.printStackTrace();
}
}
/**
* 接收数据
* @return
*/
public String receive() {
try {
return is.readUTF();
} catch (IOException e) {
this.isRunning = false;
IoUtils.closeAll(is);
e.printStackTrace();
}
return null;
}
/**
* 发送数据
* @param msg
*/
public void send(String msg) {
try {
if(msg != null && msg != "")
os.writeUTF(msg);
} catch (IOException e) {
this.isRunning = false;
IoUtils.closeAll(os);
e.printStackTrace();
}
}
/**
* 向其他客户端发送数据
* 1、私聊:以@开头+客户端名+msg. example:@c:你好
* 2、群聊
* @param msg
* @param isSysInform
*/
public void sendOthers(String msg, boolean isSysInform) {
if(msg.startsWith("@")) {
String name = msg.substring(1, msg.indexOf(":"));
String context = msg.substring(msg.indexOf(":") + 1);
for(MyChannel channel: continer) {
if(channel.name.equals(name)) {
channel.send(this.name+"悄悄对你说:"+context);
}
}
}else {
for(MyChannel channel: continer) {
if(channel == this) {
continue;
}
if(isSysInform) {
channel.send("系统消息:"+msg);
}else {
channel.send(this.name+"对大家说:"+msg);
}
}
}
}
@Override
public void run() {
while(isRunning) {
sendOthers(receive(), false);
}
}
}
}
发送线程:
package com.chen.Web.tcp.chat01;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* 发送线程:从键盘上接收数据,然后发送出去
* @author Administrator
*
*/
public class Send_Thread implements Runnable{
// 标准输入流
private BufferedReader console;
// 输入流
private DataOutputStream os;
// 标识
private boolean isRunning = true;
private String name;
public Send_Thread() {
console = new BufferedReader(new InputStreamReader(System.in));
}
public Send_Thread(Socket client, String name) {
this();
try {
os = new DataOutputStream(client.getOutputStream());
this.name = name;
send(this.name);
} catch (IOException e) {
this.isRunning = false;
IoUtils.closeAll(os, console);
e.printStackTrace();
}
}
/**
* 发送数据
* @param msg
*/
public void send(String msg) {
try {
if(msg != null && msg != "") {
os.writeUTF(msg);
}
} catch (IOException e) {
this.isRunning = false;
IoUtils.closeAll(os);
e.printStackTrace();
}
}
/**
* 把标准控制台的输入转换成字符串
* @return String
*/
public String msgFromConsole() {
try {
return console.readLine();
} catch (IOException e) {
this.isRunning = false;
IoUtils.closeAll(console);
e.printStackTrace();
}
return null;
}
@Override
public void run() {
while(isRunning) {
send(msgFromConsole());
}
}
}
接收线程:
package com.chen.Web.tcp.chat01;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
/**
* 接收线程:接收来自于socket中的字符串
* @author Administrator
*
*/
public class Receive_Thread implements Runnable{
// 输出流
private DataInputStream is;
// 标识
private boolean isRunning = true;
public Receive_Thread() {
}
public Receive_Thread(Socket client) {
try {
is = new DataInputStream(client.getInputStream());
} catch (IOException e) {
this.isRunning = false;
IoUtils.closeAll(is);
e.printStackTrace();
}
}
/**
* 接收字符串
* @return
*/
public String receive() {
try {
return is.readUTF();
} catch (IOException e) {
this.isRunning = false;
IoUtils.closeAll(is);
e.printStackTrace();
}
return null;
}
@Override
public void run() {
while(isRunning) {
System.out.println(receive());
}
}
}
工具类:
package com.chen.Web.tcp.chat01;
import java.io.Closeable;
import java.io.IOException;
/**
* 关闭流的工具类
* @author Administrator
*
*/
public class IoUtils {
public static void closeAll(Closeable ... io) {
for(Closeable temp: io) {
if(temp != null) {
try {
temp.close();
} catch (IOException e) {
System.out.println("关闭流出现异常");
e.printStackTrace();
}
}
}
}
}