22 网络编程
lix_uan 603 1

三次握手,四次挥手

22 网络编程 22 网络编程

Socket

22 网络编程

群聊

客户端

package com.atguigu.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

/*
 * 群聊
 */
public class Client4 {
    public static void main(String[] args) throws UnknownHostException, IOException {
        // 1、连接服务器
        Socket socket = new Socket("127.0.0.1", 9999);

        // 2、开启两个线程,一个收消息,一个发消息
        SendThread st = new SendThread(socket);
        ReceiveThread rt = new ReceiveThread(socket);

        st.start();
        rt.start();

        // 等发送线程停下来再往下走
        try {
            st.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 等接收线程停下来,再往下走,断开连接
        try {
            rt.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        socket.close();
    }

    static class SendThread extends Thread {
        private Socket socket;

        public SendThread(Socket socket) {
            super();
            this.socket = socket;
        }

        public void run() {
            try {
                // 键盘输入
                Scanner input = new Scanner(System.in);
                OutputStream out = socket.getOutputStream();
                PrintStream ps = new PrintStream(out);
                while (true) {
                    // 从键盘输入
                    System.out.print("请输入要发送的消息:");
                    String content = input.nextLine();

                    // 给服务器发送
                    ps.println(content);

                    // 如果bye,就结束发送
                    if ("bye".equals(content)) {
                        break;
                    }
                }
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    static class ReceiveThread extends Thread {
        private Socket socket;

        public ReceiveThread(Socket socket) {
            super();
            this.socket = socket;
        }

        public void run() {
            try {
                InputStream in = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(in);
                BufferedReader br = new BufferedReader(isr);

                while (true) {
                    String line = br.readLine();
                    if("bye".equals(line)){
                        break;
                    }
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

服务端

package com.atguigu.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;

public class Server4 {
    private static ArrayList<Socket> online = new ArrayList<Socket>();

    public static void main(String[] args) throws IOException {
        //1、开启服务器
        ServerSocket server = new ServerSocket(9999);

        while(true){
            //2、接收客户端的连接
            Socket socket = server.accept();

            //把这个客户端加入到online中
            online.add(socket);

            //每一个客户端独立的线程
            MessageHandler mh = new MessageHandler(socket);
            mh.start();
        }
    }

    private static class MessageHandler extends Thread{
        private Socket socket;
        private String ip;

        public MessageHandler(Socket socket) {
            super();
            this.socket = socket;
            this.ip = socket.getInetAddress().getHostAddress();
        }

        public void run(){
            //这个客户端的一连接成功,线程一启动,就可以告诉其他人我上线了
            sendToOthers(ip+"上线了");

            //(1)接收当前的客户端发送的消息
            try {
                InputStream in = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(in);
                BufferedReader br = new BufferedReader(isr);

                String content;
                while((content = br.readLine()) !=null){
                    //收到一句,转发一句
                    sendToOthers(ip+"说:" + content);

                    if("bye".equals(content)){
                        //给自己发一句bye
                        OutputStream out = socket.getOutputStream();
                        PrintStream ps = new PrintStream(out);
                        ps.println("bye");

                        break;
                    }
                }
                sendToOthers(ip+"下线了");
            } catch (IOException e) {
                sendToOthers(ip+"掉线了");
            }
        }

        //因为转发的代码也很长,独立为一个方法
        public void sendToOthers(String str){
            //遍历所有online的客户端
            Iterator<Socket> iterator = online.iterator();
            while(iterator.hasNext()){
                Socket on = iterator.next();
                if(!on.equals(socket)){//只给其他客户端转发
                    try {
                        OutputStream out = on.getOutputStream();
                        PrintStream ps = new PrintStream(out);

                        ps.println(str);
                    } catch (IOException e) {
                        //说明on这个客户端要么下线了,要么掉线了
                        iterator.remove();
                    }
                }
            }
        }
    }    
}

UDP广播

package com.atguigu.net;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.Scanner;

public class GuangBo {
    private volatile static boolean exit = false;
    private static Scanner input = new Scanner(System.in);

    public static void main(String[] args) throws IOException {
        MulticastSocket socket = new MulticastSocket(9999);
        InetAddress ip = InetAddress.getByName("230.0.0.1");
        socket.joinGroup(ip);
        socket.setLoopbackMode(false);

        SendThread s = new SendThread(socket, ip);
        ReceiveThread r = new ReceiveThread(socket);

        s.start();
        r.start();

        try {
            s.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        socket.close();
        input.close();
    }

    static class SendThread extends Thread {
        private MulticastSocket socket;
        private InetAddress ip;

        public SendThread(MulticastSocket socket, InetAddress ip) {
            super();
            this.socket = socket;
            this.ip = ip;
        }

        public void run() {
            try {
                while (!exit) {
                    System.out.print("输入广播消息:");
                    String message = input.nextLine();
                    if ("bye".equals(message)) {
                        exit = true;
                        break;
                    }

                    byte[] data = (socket.getInetAddress().getHostAddress() + ":" + message).getBytes();
                    DatagramPacket dp = new DatagramPacket(data, data.length, ip, 9999);

                    socket.send(dp);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    static class ReceiveThread extends Thread {
        private MulticastSocket socket;

        public ReceiveThread(MulticastSocket socket) {
            super();
            this.socket = socket;
        }

        public void run() {
            try {
                while (!exit) {
                    byte[] data = new byte[1024];
                    DatagramPacket dp = new DatagramPacket(data, data.length);
                    socket.receive(dp);
                    String str = new String(data, 0, dp.getLength());
                    System.out.println(str);
                }
            } catch (IOException e) {
                exit = false;
            }
        }
    }
}
评论区

索引目录