再多学一点吧

导航

网络编程

获取ip地址

   InetAddress类成员方法
        * static InetAddress getLocalHost()
            * 获得本地主机IP地址对象
        * static InetAddress getByName(String host)
            * 根据IP地址字符串或主机名获得对应的IP地址对象

        * String getHostName();获得主机名
        * String getHostAddress();获得IP地址字符

public class InetAddressDemo {
    public static void main(String[] args) throws UnknownHostException {
        InetAddress byName = InetAddress.getByName("DESKTOP-SDL9NNV");
        System.out.println(byName);    //  DESKTOP-SDL9NNV/192.168.3.26
        InetAddress byName1 = InetAddress.getByName("192.168.3.26");
        System.out.println(byName1);  //  /192.168.3.26

        String s1 = byName.getHostName();
        System.out.println(s1);//DESKTOP-SDL9NNV
        String s2 = byName.getHostAddress();
        System.out.println(s2);//192.168.3.26

   }
}

UDP协议的特点
    * 面向无连接的协议
    * 发送端只管发送,不确认对方是否能收到。
    * 基于数据包进行数据传输。
    * 发送数据的大小限制64K以内
    * 因为面向无连接,速度快,但是不可靠。

UDP协议的使用场景
    * 即时通讯
    * 在线视频
    * 网络语音电话

UDP协议相关的两个类
    * DatagramPacket
        * 数据包对象
        * 作用:用来封装要发送或要接收的数据,比如:集装箱
    * DategramSocket
        * 发送对象
        * 作用:用来发送或接收数据包,比如:码头

DatagramPacket类构造方法
    * DatagramPacket(byte[] buf, int length, InetAddress address, int port)
        * 创建发送端数据包对象
        * buf:要发送的内容,字节数组
        * length:要发送内容的长度,单位是字节
        * address:接收端的IP地址对象
        * port:接收端的端口号
    * DatagramPacket(byte[] buf, int length)
        * 创建接收端的数据包对象
        * buf:用来存储接收到内容
        * length:能够接收内容的长度

DatagramPacket类常用方法
    * int getLength() 获得实际接收到的字节个数

    * byte[] getData() 返回数据缓冲区

DatagramSocket类构造方法
    * DatagramSocket() 创建发送端的Socket对象,系统会随机分配一个端口号。
    * DatagramSocket(int port) 创建接收端的Socket对象并指定端口号

DatagramSocket类成员方法
    * void send(DatagramPacket dp) 发送数据包
    * void receive(DatagramPacket p) 接收数据包

public class SendDemo {
    public static void main(String[] args) throws IOException {
        while (true) {
            Scanner sc = new Scanner(System.in);
            String s = sc.next();
            // 创建数据包对象
            DatagramSocket ds = new DatagramSocket();

            //创建发送端的发送对象,因为其构造方法需要字节数组,所以将输入内容转换为字节数组
            byte[] bytes = s.getBytes();
            DatagramPacket dp = new DatagramPacket(bytes, bytes.length,
                    InetAddress.getByName("DESKTOP-SDL9NNV"), 10086);

            // 发送数据包
            ds.send(dp);
            //关闭数据包
            ds.close();
        }
    }
}

public class ReceiveDemo {
    public static void main(String[] args) throws IOException {

        while (true) {
            // 创建接收对象DatagramSocket,注意作为接受端需要接受传入的端口号
            DatagramSocket ds = new DatagramSocket(10086);

            // 创建数据包对象,此刻的数据包需要先定义出包的大小,所以先创建数组
            byte[] bytes = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bytes, bytes.length);

            // 接收数据包
            ds.receive(dp);

            //输入数据,注意需要输入到指定长度 dp.getLength()
            String s = new String(dp.getData(), 0, dp.getLength());
            System.out.println(dp.getAddress().getHostName() + "收到:" + s);
            ds.close();
        }
    }
}

TCP ==> Transfer Control Protocol ==> 传输控制协议
TCP协议的特点
    * 面向连接的协议
    * 只能由客户端主动发送数据给服务器端,服务器端接收到数据之后,可以给客户端响应数据。
    * 通过三次握手建立连接,连接成功形成数据传输通道。
    * 通过四次挥手断开连接
    * 基于IO流进行数据传输
    * 传输数据大小没有限制
    * 因为面向连接的协议,速度慢,但是是可靠的协议。

TCP协议的使用场景
    * 文件上传和下载
    * 邮件发送和接收
    * 远程登录

TCP协议相关的类
    * Socket
        * 一个该类的对象就代表一个客户端程序。
    * ServerSocket
        * 一个该类的对象就代表一个服务器端程序。

Socket类构造方法
    * Socket(String host, int port)
        * 根据ip地址字符串和端口号创建客户端Socket对象
        * 注意事项:只要执行该方法,就会立即连接指定的服务器程序,如果连接不成功,则会抛出异常。
            如果连接成功,则表示三次握手通过。

Socket类常用方法
    * OutputStream getOutputStream(); 获得字节输出流对象
    * InputStream getInputStream();获得字节输入流对象

    *SocketAddress getRemoteSocketAddress()   返回此套接字连接,或端点的地址 null如果是未连接

public class SendDemo {
    public static void main(String[] args) throws IOException {
        System.out.println("客户端启动");
        // 创建Socket对象,注意传入ip地址和端口,Socket其实就一个管道
        Socket s = new Socket("192.168.3.26",10086);

        // 获得字节输出流对象
        OutputStream os = s.getOutputStream();

        //将其封装成打印流直接输入
        PrintStream ps = new PrintStream(os);
        Scanner sc = new Scanner(System.in);
        while (true) {
            ps.println(sc.next());

        }
    }
}

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        System.out.println("服务器启动");
        // 创建服务器ServerSocket对象,传入端口
        ServerSocket ss = new ServerSocket(10086);

        // ServerSocket接受到管道Socket
        Socket s = ss.accept();

        //读取管道接收的数据  s.getInputStream()
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));

        //进行循环输出到控制台
        String line;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }
        
    }
}

多线程实现客户端与服务端的传输:通过管道Socket来进行多线程

public class ClientDemo2 {
    public static void main(String[] args) throws IOException {
        //创建Socket管道,传入ip地址和端口号
        Socket s = new Socket("192.168.3.26",10086);
        //创建缓冲池得到字节输出流
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        //通过训话实现字符的write方法
        while (true){
            Scanner sc = new Scanner(System.in);
            bw.write(sc.next());
            bw.newLine(); //如果没有空行,读取数据通过readline无法读取
            bw.flush();
        }
    }
}
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        System.out.println("\t\t\t\t\t群聊:团团圆圆一家人");
        //创建ServerSocket对象
        ServerSocket ss = new ServerSocket(10086);
        //因为不知道几个客户端,所有用循环来对线程进行实现
        while (true){
            Socket s = ss.accept();
            Thread t = new Thread(new ServerThread(s));
            t.start();
        }


    }
}

class ServerThread implements Runnable{
    private Socket s;
    
    public ServerThread(Socket s) {
        this.s=s;
    }
    //多线程实现run方法,里面需要写的无疑是数据的读取
    @Override
    public void run() {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            Date now = new Date();
            String line;
            while ((line=br.readLine())!=null){
                System.out.print(now+":");
                System.out.println(s.getRemoteSocketAddress()+"\t发言:\t"+line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

 

posted on 2021-08-24 14:10  糟糟张  阅读(48)  评论(0编辑  收藏  举报