来源:http://www.bjsxt.com/
一、S02E191_01网络编程TCP_Socket通信聊天室_客户端多线程
二、S02E192_01网络编程TCP_Socket通信聊天室_群聊
package com.test.net.tcp.chat;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 创建客户端:发送数据+接收数据
* 写出数据:输出流
* 读取数据:输入流
*
* 输入流与输出流应该独立处理,彼此独立,在不同的线程中
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket client = new Socket("LWT-PC",9999);
//控制台输入流
new Thread(new Send(client)).start();//一条路径
new Thread(new Receive(client)).start();//一条路径
}
}
package com.test.net.tcp.chat;
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;
/**
* 创建服务器
* 写出数据:输出流
* 读取数据:输入流
*/
public class Server {
private List<MyChannel> all = new ArrayList<MyChannel>();
public static void main(String[] args) throws IOException {
new Server().start();
}
public void start() throws IOException{
ServerSocket server = new ServerSocket(9999);
while(true){
Socket client = server.accept();
MyChannel channel = new MyChannel(client);
all.add(channel);//统一管理
new Thread(channel).start();//一条道路
}
}
/**
* 一个客户端一条道路
* 1、输入流
* 2、输出流
* 3、接收数据
* 4、发送数据
*/
private class MyChannel implements Runnable{
private DataInputStream dis;
private DataOutputStream dos;
private boolean isRunning = true;
public MyChannel(Socket client) {
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dis,dos);
isRunning = false;
}
}
/**
* 读取数据
* @return
*/
private String receive(){
String msg = "";
try {
msg = dis.readUTF();
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dis);
isRunning = false;
all.remove(this);//移除自身
}
return msg;
}
/**
* 发送数据
*/
private void send(String msg){
if(null==msg || msg.equals("")){
return;
}
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dos);
isRunning = false;
all.remove(this);//移除自身
}
}
/**
* 发送给其它客户端
*/
private void sendOthers(){
String msg = this.receive();
//遍历容器
for (MyChannel other : all) {
if(other==this){
continue;
}
//发送给其它客户端
other.send(msg);
}
}
@Override
public void run() {
while(isRunning){
sendOthers();
}
}
}
}
package com.test.net.tcp.chat;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* 发送数据线程
*/
public class Send implements Runnable{
//控制台输入流
private BufferedReader console;
//管道输出流
private DataOutputStream dos;
//控制线程
private boolean isRunning = true;
public Send() {
console = new BufferedReader(new InputStreamReader(System.in));
}
public Send(Socket client) {
this();
try {
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
//e.printStackTrace();
isRunning = false;
CloseUtil.closeAll(dos,console);
}
}
//1、从控制台接收数据
private String getMsgFromConsole(){
try {
return console.readLine();
} catch (IOException e) {
//e.printStackTrace();
}
return "";
}
/**
* 1、从控制台接收数据
* 2、发送数据
*/
public void send(){
String msg = getMsgFromConsole();
if(null!=msg && !msg.equals("")){
try {
dos.writeUTF(msg);
dos.flush();//强制刷新
} catch (IOException e) {
//e.printStackTrace();
isRunning = false;
CloseUtil.closeAll(dos,console);
}
}
}
@Override
public void run() {
while(isRunning){
send();
}
}
}
package com.test.net.tcp.chat;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
/**
* 接收数据线程
*/
public class Receive implements Runnable {
//输入流
private DataInputStream dis;
//线程标识
private boolean isRunning = true;
public Receive() {
}
public Receive(Socket client){
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
//e.printStackTrace();
isRunning = false;
CloseUtil.closeAll(dis);
}
}
/**
* 接收数据
*/
public String receive(){
String msg = "";
try {
msg = dis.readUTF();
} catch (IOException e) {
//e.printStackTrace();
isRunning = false;
CloseUtil.closeAll(dis);
}
return msg;
}
@Override
public void run() {
while(isRunning){
System.out.println(receive());
}
}
}
package com.test.net.tcp.chat;
import java.io.Closeable;
import java.io.IOException;
/**
* 关闭流的方法
*/
public class CloseUtil {
public static void closeAll(Closeable...io){
for (Closeable temp : io) {
if(null!=temp){
try {
temp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}