利用多线程实现多个客户端向服务器发送数据并接收数据的功能
服务端:
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 ChatServer {
private List<Others> list=new ArrayList<Others>();
public static void main(String[] args) throws IOException {
new ChatServer().start();
}
public void start() throws IOException {
ServerSocket server=new ServerSocket(9999);
int i=1;
while(true){
Socket socket=server.accept();//接收客户端的请求
System.out.println("hello: "+i+"号");
Others channer=new Others(socket);
channer.setNum(i);//设置每个通道的编号
list.add(channer);//把通道放进容器中
new Thread(channer).start();
i++;
}
}
private class Others implements Runnable{//数据传输通道
private DataInputStream dis=null;
private DataOutputStream dos=null;
private boolean flag=true;
private String name;
private boolean xitong=false;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
private int num=0;
public Others() {
}
public Others(Socket client){
try {
dis=new DataInputStream(client.getInputStream());
dos=new DataOutputStream(client.getOutputStream());
name=dis.readUTF();
send("欢迎进入聊天室");
sendOthers("系统消息:"+name+"进入了聊天室",xitong=true);
} catch (IOException e) {
CloseUtil.closeAll(dis,dos);
list.remove(this);
flag=false;
}
}
public String receive(){
String mes="";
try {
mes=dis.readUTF();
} catch (IOException e) {
CloseUtil.closeAll(dis);
list.remove(this);
flag=false;
}
return mes;
}
public void send(String mes){
try {
dos.writeUTF(mes);
dos.flush();
} catch (IOException e) {
CloseUtil.closeAll(dos);
list.remove(this);
flag=false;
}
}
public void sendOthers(String mes,boolean xitong){
if(mes.startsWith("@")&&(mes.indexOf(":")>0)){
String name=mes.substring(1,mes.indexOf(":"));
String content=mes.substring(mes.indexOf(":")+1);
for(Others other:list){
if(other.name.equals(name)){
other.send(this.name+"对你说:"+content);
}
}
}else{
for(Others other:list){
if(other==this){
continue;
}
if(xitong){
other.send(mes);
}else{
other.send(this.name+":"+mes);
}
}
xitong=false;
}
}
@Override
public void run() {
while(flag) {
sendOthers(receive(),xitong);
}
}
}
}
客户端:
import java.io.*;
import java.net.Socket;
/**
* 客户端发送数据的线程
*/
public class Send implements Runnable{
private BufferedReader is;
private DataOutputStream dos;
private boolean flag=true;
public Send() {
is=new BufferedReader(new InputStreamReader(System.in));
}
public Send(Socket client) throws IOException {
this();
try {
dos=new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
CloseUtil.closeAll(dos,is);
flag=false;
}
}
//获取数据
public String getMes(){
String mes=null;
try {
mes=is.readLine();
} catch (IOException e) {
CloseUtil.closeAll(dos,is);
flag=false;
mes="";
}
return mes;
}
//发送数据
private void send() throws IOException {
String mes=getMes();
if(null!=mes&&!mes.equals("")){
try {
dos.writeUTF(mes);
dos.flush();
} catch (IOException e) {
CloseUtil.closeAll(dos,is);
flag=false;
}
}
}
@Override
public void run() {
while(flag){
try {
send();
} catch (IOException e) {
CloseUtil.closeAll(dos,is);
flag=false;
}
}
}
}
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) {
isRunning=false;
CloseUtil.closeAll(dis);
}
}
public void receive(){
String mes="";
try {
mes=dis.readUTF();
} catch (IOException e) {
isRunning=false;
CloseUtil.closeAll(dis);
}
System.out.println(mes);
}
@Override
public void run() {
while(isRunning){
receive();
}
}
}
import java.io.*;
import java.net.Socket;
/**
* 创建客户端+发送数据+接收数据
*/
public class ChatClient {
public static void main(String[] args) throws IOException {
Socket client=new Socket("localhost",9999);
System.out.println("请输入姓名:");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String name=br.readLine();
//控制台输入流
new Thread(new Send(client,name)).start();
new Thread(new Receive(client)).start();
}
}
import java.io.Closeable;
import java.io.IOException;
/**
* 关闭流的工具类
*/
public class CloseUtil{
public static void closeAll(Closeable... io){
for(Closeable temp:io){
if(temp!=null){
try {
temp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}