java实现网络编程

1、什么是网络编程:
网络编程就是通过写的一段程序代码在多台计算机中相互交换数据
2、网络编程三要素:
ip地址:想让网络中的计算机相互通信,必须为每台计算机都指定一个标识符,来指定接收数据,ip就是这个标识符,也是设备的标识。
端口:网络通信本质上是两个应用程序的通信,计算机中有很多的应用程序,可以说ip地址是两台计算机通信的标识符,那么端口就是应用程序的标识符。
通信协议:是计算机相互通信需要遵守的规则,它对传输速率,传输格式等一些有具体的规定,只有双方都遵守规定才可以进行数据交换。常用的协议有UDP和TCP协议
3、InetAdress类的使用
这个类没有构造方法(所以不能直接使用new关键字)但是可以用静态的方法(InetAddress.getByName(“String”);String 可以是主机名或者是主机IP地址)来获得。通过InterAddress.getHostName()获取当前主机的名字;通过InterAddress.getHostAddress()获取当前主机IP地址,都是通过文本形式返回的。

public static void main(String[] args) throws UnknownHostException {
        InetAddress inetAddress =InetAddress.getByName("192.168.3.3");//通过静态方法getByName获得
        String name=inetAddress.getHostName();//通过文本形式显示当前主机名
        String address=inetAddress.getHostAddress();//通过文本形式获得当前主机IP地址
        System.out.println(name);
        System.out.println(address);
    }

在这里插入图片描述

什么是UDP协议:UDP是用户数据报协议的缩写,一个无连接的协议。提供了应用程序之间要发送的数据的数据包。
UDP发送数据步骤:
1、创建一个socket对象,
2、创建数据包,并把数据打包
3、调用DatagramSocket对象发送数据
4、关闭发送端

		//1、创建一个socket对象
        DatagramSocket ds = new DatagramSocket();
        //2、创建数据包,并把数据打包
        byte [] bys="hello,UDP".getBytes();
        //创建一个DatagramPack数据报包对象
        DatagramPacket dp = new DatagramPacket(bys,bys.length,InetAddress.getByName("192.168.3.3"),10086);
        // 3、调用DatagramSocket对象发送数据
        ds.send(dp);
        // 4、关闭发送端
        ds.close();

UDP接收数据步骤:
1、创建一个socket对象,
2、创建数据包,并把数据打包
3、调用DatagramSocket对象中的方法接收数据
4、解析数据,并在控制台显示
4、关闭接收端

//    UDP接收数据步骤:
    public static void main(String[] args) throws IOException {
        //1、创建一个DatagramSocket对象
        DatagramSocket ds = new DatagramSocket(10086);
//2、创建数据包,并把数据打包
        byte[] bys=new byte[1024];
        DatagramPacket dp = new DatagramPacket(bys, bys.length);
//3、调用DatagramSocket对象中的方法接收数据
        ds.receive(dp);
//4、解析数据,并在控制台显示
        System.out.println("数据是:"+new String(dp.getData(),0,bys.length));
//4、关闭接收端
        ds.close();
    }

什么是TCP协议:TCP是一种可靠的网络协议,它在通信的两端都建立了socker对象,从而在通信的两端形成网络虚拟链路。Java为TCP协议的通信提供了很好的封装,使用socket对象表示通信两端的端口,并通过socker对象产生的IO流来进行网络通信,Java为客户端提供Socket类,为服务端提供ServerSocket类
TCP协议发送数据步骤:
1、创建Socket对象
2、获取输出流,写数据
3、释放资源

public static void main(String[] args) throws IOException {
        Socket socket = new Socket("192.168.3.3",10000);//创建Socket对象,指定Host和port
        OutputStream outputStream = socket.getOutputStream();//获取输出流,写数据
        outputStream.write("hello,tcp".getBytes());//写数据
        socket.close();//释放资源
    }

TCP协议接收数据步骤:
1、创建ServerSocket对象
2、监听客户端连接,返回一个socket对象
2、获取输入流,读数据,并显示在控制台上
3、释放资源

public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(10000);//创建ServerSocket对象,指定port
        Socket ss = serverSocket.accept();//监听客户端的连接
        InputStream is = ss.getInputStream();//获取输入流,读数据
        byte[] bys=new byte[1024];
        System.out.println("数据是:"+new String(bys,0,is.read(bys)));//解析数据,并显示在控制台上
        serverSocket.close();//释放资源
    }

TCP通信练习:
1、客户端获取键盘输入,886作为结束 服务端接受客户端输入。

public class test05_Client {
    public static void main(String[] args) throws IOException {
        //创建Socket对象
        Socket s = new Socket("192.168.3.3",10000);
        //获取输出流对象
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//从键盘录入数据
        //封装输出流对象
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while ((line=br.readLine())!=null){
            if("886".equals(line)){
                break;
            }
            bw.write(line);//将指定的字节写入缓冲的输出流。
            bw.newLine();//写一个行分隔符。
            bw.flush();//刷新缓冲输出流。
        }
        s.close();

    }
}
public class test05_Server {
    public static void main(String[] args) throws IOException {
        //创建一个ServerSocket对象
        ServerSocket ss = new ServerSocket(10000);
        //监听
        Socket s = ss.accept();
        //获取输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        //解析数据,显示在控制台上
        String line;
        while ((line=br.readLine())!=null){//确保获取内容不为空
            System.out.println(line);
        }
        ss.close();
    }
}

2、客户端获取键盘输入,886作为结束 服务端接受客户端输入,存储到文本中。
因为客户端和1一致就不贴代码了

public class test05_Server {
    public static void main(String[] args) throws IOException {
        //创建一个ServerSocket对象
        ServerSocket ss = new ServerSocket(10000);
        //监听
        Socket s = ss.accept();
        //获取输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String line;
        BufferedWriter bw = new BufferedWriter(new FileWriter("text.txt",true));//写内容到文件中,追加方式写进
        while ((line=br.readLine())!=null){//确保获取内容不为空
            bw.append(line);
            bw.newLine();
            bw.flush();
        }
        bw.close();
        ss.close();
    }
}

3、客户端获取文本文件内容获得服务端给出的反馈 服务端接受客户端输入,存储到文本中,给客户端一个反馈。

Socket s = new Socket("192.168.3.3",10000);
        BufferedReader br = new BufferedReader(new FileReader("textClient.txt"));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while ((line=br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        //void	shutdownOutput()
        //Disables the output stream for this socket.
        s.shutdownOutput();//Disables the output stream for this socket.
        //接收反馈
        BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));
        System.out.println("服务器的反馈"+brClient.readLine());
        br.close();
        s.close();

在写服务器反馈遇到的问题是,客户端在读取完文本文件后开始获取服务端的反馈,但是服务器端仍然在等待客户端发送数据,没有结束等待。解决办法:在客户端读取文本文件结束后,调用shutdownOutput()方法来告诉服务端已经停止读取了。也可以自定义一个结束标记但是不推荐使用

public static void main(String[] args) throws IOException {
        //创建一个ServerSocket对象
        ServerSocket ss = new ServerSocket(10000);
        //监听
        Socket s = ss.accept();
        //获取输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String line;
        BufferedWriter bw = new BufferedWriter(new FileWriter("textServer.txt",true));//写内容到文件中,追加方式写进
        while ((line=br.readLine())!=null){//确保获取内容不为空
            bw.append(line);
            bw.newLine();
            bw.flush();
        }
        //给出反馈
        BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        bwServer.write("文件上传成功");
        bwServer.newLine();
        bwServer.flush();
        bw.close();
        ss.close();
    }

4、客户端获取文本文件内容 服务端接受客户端输入,存储到文本中,代码用线程封装一个客户端一个线程。

ServerSocket ss = new ServerSocket(10000);
        Socket s = ss.accept();
        //为每一个客户端开启一个线程
        new Thread(new ServerThread(s)).start();
class ServerThread implements Runnable {
    private Socket s;
    public ServerThread(Socket s) {
        this.s=s;
    }

     @Override
     public void run() {
         try {
             int count=0;
             BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
             //避免文件名重复
             File file = new File("text[" + count + "].txt");
             String line;
             while (file.exists()){
                 count++;
                 file = new File("text[" + count + "].txt");
             }
             BufferedWriter bw = new BufferedWriter(new FileWriter(file));
             while ((line=br.readLine())!=null){
                 bw.write(line);
                 bw.newLine();
                 bw.flush();
             }
//             给出反馈
             BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
             bwServer.write("文件上传成功");
             bwServer.newLine();
             bwServer.flush();
             s.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }

实现客户端传数据给服务端,服务端判断数据是否正确并告知客户端
(实现账号密码登录功能并加入多线程)

package com.socket.socket2;

import java.io.*;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {
        /*
         * 客户端
         * */
        Socket socket = null;
        boolean flag;
        try {
            socket = new Socket("localHost", 9000);
            //获取用户输入
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            //向服务器反馈数据
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            //接受服务端返溃数据
            DataInputStream dis = new DataInputStream(socket.getInputStream());
            while (true) {
                System.out.println("用户名:");
                String name = br.readLine();
                System.out.println("密码:");
                String password = br.readLine();
                //封装数据
                User user = new User(name, password);
                oos.writeObject(user);
                //接受服务器返溃数据
                flag = dis.readBoolean();
                //如果成功则返回true
                if (flag) {
                    System.out.println("登陆成功");
                    break;
                } else {
                    System.out.println("用户名或密码错误");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(socket !=null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

服务端

package com.socket.socket2;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) {
        /*
         * 服务端
         * */
        ServerSocket ss = null;
        Socket socket = null;
        try {
            ss = new ServerSocket(9000);
            while (true) {
                socket = ss.accept();
                System.out.println(socket.getInetAddress().getHostName() + "连接成功");
                //    实现多线程
                ServerRunnable serverRunnable = new ServerRunnable(socket);
                new Thread(serverRunnable).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

多线程

package com.socket.socket2;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;

public class ServerRunnable implements Runnable {
    private Socket socket;

    public ServerRunnable() {
    }

    public ServerRunnable(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            boolean flag = false;
            //获取客户端发的数据
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            while (true) {
                User user = (User) ois.readObject();
                if (user.getName().equals("admin") && user.getPassword().equals("abc")) {
                    System.out.println("登陆成功");
                    flag = true;
                } else if (user.getName().equals("user") && user.getPassword().equals("123")) {
                    System.out.println("登陆成功");
                    flag = true;
                } else {
                    System.out.println("登陆失败");
                }
                dos.writeBoolean(flag);
                if (flag) {
                    break;
                }
                else {
                    System.out.println("失败");
                }
            }

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

用户类

package com.socket.socket2;

import java.io.Serializable;
import java.util.Objects;

public class User implements Serializable {
    private String name;
    private String password;
    public static final long serialVersionUID=1L;

    public User() {
    }

    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        User user = (User) o;
        return Objects.equals(name, user.name) && Objects.equals(password, user.password);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, password);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值