java19 先开服务器,再开客户端

先开服务器,再开客户端。

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * 创建服务器
 * 写出数据:输出流
 * 读取数据:输入流
 */
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server =new ServerSocket(9999);
        Socket client =server.accept();
        //写出数据
        //输入流
        DataInputStream dis = new DataInputStream(client.getInputStream());
        String msg =dis.readUTF();
        //输出流
        DataOutputStream dos = new DataOutputStream(client.getOutputStream());
        dos.writeUTF("服务器-->"+msg);
        dos.flush();
    }
}



import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
/**
 * 创建客户端: 发送数据+接收数据
 * 写出数据:输出流
 * 读取数据:输入流
 */
public class Client {
    public static void main(String[] args) throws UnknownHostException, IOException {
        Socket client = new Socket("localhost",9999);
        //把控制台输入封装成输入流
        BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
        DataOutputStream dos = new DataOutputStream(client.getOutputStream());
        DataInputStream dis = new DataInputStream(client.getInputStream());
        while(true){
            String info =console.readLine();//根据输入的换行符读取一行。
            //输出流,输出去在读进来。
            dos.writeUTF(info);
            dos.flush();
            //输入流
            String msg =dis.readUTF();
            System.out.println(msg);
        }
    }
}



聊天室:
1. 客户端可以发送数据 +接收数据 独立的
2. 每个客户端创建一个线程,彼此相互独立。

输入流 与输出流 在同一个线程内 应该 独立处理,彼此独立。

a客户端发送数据给服务器,服务器中转给b、c客户端。所以服务器要为每一个客户端建立一个线程。服务器为每一个客户端服务时,每个客户端都有输入流和输出流,客户端的输入流和输出流也是独立的所以也是线程。并且有私聊的功能。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 创建客户端: 发送数据+接收数据
 * 写出数据:输出流
 * 读取数据:输入流
 * 
    输入流 与输出流 在同一个线程内 应该 独立处理,彼此独立
    
    加入名称
 */
public class Client {
    public static void main(String[] args) throws UnknownHostException, IOException {
        System.out.println("请输入名称:");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String name = br.readLine();
        if(name.equals("")){
            return;
        }    
        Socket client = new Socket("localhost",9999);
        new Thread(new Send(client,name)).start(); //一条路径
        new Thread(new Receive(client)).start(); //一条路径    
    }
}


/**
 * 接收线程 
 */
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());
        }
    }
}




/**
 * 发送数据 线程
 */
public class Send implements Runnable{
    //控制台输入流
    private BufferedReader console;
    //管道输出流
    private DataOutputStream dos;
    //控制线程
    private boolean isRunning =true;
    //名称
    private String name;
    public Send() {
        console =new BufferedReader(new InputStreamReader(System.in));
    }
    public Send(Socket client,String name){
        this();
        try {
            dos =new DataOutputStream(client.getOutputStream());
            this.name =name;
            send(this.name);
        } 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){
        try {
            if(null!=msg&& !msg.equals("")){
                dos.writeUTF(msg);
                dos.flush(); //强制刷新
            }
        } catch (IOException e) {
            //e.printStackTrace();
            isRunning =false;
            CloseUtil.closeAll(dos,console);
        }
    }
    
    
    @Override
    public void run() {
        //线程体
        while(isRunning){
            send(getMsgFromConsole());
        }
    }

}


/**
 * 创建服务器
 * 写出数据:输出流
 * 读取数据:输入流
 */
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;
        private String name; 
        public MyChannel(Socket client ) {
            try {
                dis = new DataInputStream(client.getInputStream());
                dos = new DataOutputStream(client.getOutputStream());                
                this.name =dis.readUTF();                
                this.send("欢迎您进入聊天室");
                sendOthers(this.name+"进入了聊天室",true);
            } 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,boolean sys){
            //是否为私聊 约定
            if(msg.startsWith("@")&& msg.indexOf(":")>-1 ){ //私聊
                //获取name
                String name =msg.substring(1,msg.indexOf(":"));
                String content = msg.substring(msg.indexOf(":")+1);
                for(MyChannel other:all){
                    if(other.name.equals(name)){
                        other.send(this.name+"对您悄悄地说:"+content);
                    }
                }
            }else{        
                //遍历容器
                for(MyChannel other:all){
                    if(other ==this){
                        continue;
                    }
                    if(sys){ //系统信息
                        other.send("系统信息:"+msg);
                    }else{
                        //发送其他客户端
                        other.send(this.name+"对所有人说:"+msg);
                    }
                }
            }
        }
        
        
        @Override
        public void run() {
            while(isRunning){
                sendOthers(receive(),false);
            }
        }
    }
    

}




/**
 * 关闭流的方法
 */
public class CloseUtil {
    public static void closeAll(Closeable... io){
        for(Closeable temp:io){
            try {
                if (null != temp) {
                    temp.close();
                }
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }
}

 

posted @ 2015-09-23 21:54  无天666  阅读(462)  评论(0)    收藏  举报