Java高级特性:网络编程

IP地址(Internet  Protocol):唯一标识网络上的每一台计算机
IP地址的组成:32位,由4个8位二进制数组成
IP地址 = 网络地址 +主机地址
网络地址:标识计算机或网络设备所在的网段
主机地址:标识特定主机或网络设备

 查看本机的IP地址:ipconfig

测试网络是否通畅:ping  目标IP地址

网络通信协议:为了在网络中不同的计算机之间进行通信而建立的规则、标准或约定的集合

一、Socket

通信链路的端点就被称为“套接字”(英文名Socket ):是提供给应用程序的接口
Socket的底层机制复杂,Java平台提供了一些简单的API,可以更简单有效的使用Socket开发而无需了解底层机制
基于TCP协议的Socket编程
基于TCP协议的Socket网络通信: 用来实现双向安全连接网络通信

1、Socket通信模型

进行网络通信时,Socket 需要借助数据流来完成数据的传递工作

2、Socket网络编程一般可以分成如下步骤进行

1、建立连接

2、打开Socket关联的输出入输出流

3、数据流种读写信息

4、关闭所有的数据流和Socket

实例:

建立客户端

public class Client {
    public static void main(String[] args) {

        try {
            //建立客户端socket连接,指定服务器的位置为本机以及端口为8080
            Socket socket = new Socket("127.0.0.1",8080);
            System.out.println("****************客户端已启动***************");
            //打开输出流
            OutputStream os = socket.getOutputStream();
            //打开输入流
            InputStream is = socket.getInputStream();
            //发送客户端信息,即向输出流写入信息
            String info = "用户名:tom;用户密码:123456";
            os.write(info.getBytes(StandardCharsets.UTF_8));
            socket.shutdownOutput();
            //接收服务器端的响应,即从输入流读取信息
            String replay = null;
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            while ((replay = br.readLine()) != null){
                System.out.println("我是客户端,服务器端响应为:" + replay);
            }
            //关闭资源
            os.flush();
            os.close();
            is.close();
            br.close();
            socket.close();

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

    }
}

建立服务端

public class Server {
    public static void main(String[] args)  {
        try {
            //建立客户端serverSocket连接,指定服务器的位置为本机以及端口为8080
            ServerSocket serverSocket = new ServerSocket(8080);
            System.out.println("****************服务端已启动***************");
            //使用accept()方法等待客户端发起通信
            Socket socket = serverSocket.accept();
            //打开输入流
            InputStream is = socket.getInputStream();
            //打开输出流
            OutputStream os = socket.getOutputStream();
            //获取客户信息,从输入流读取信息
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String info = null;

            while ((info = br.readLine()) != null){
                System.out.println("我是服务器,客户登录信息为:" + info);
            }
            //给客户端一个响应
            String reply = "欢迎您,登录成功!";
            //
            os.write(reply.getBytes(StandardCharsets.UTF_8));
            //关闭资源
            os.flush();
            os.close();
            is.close();
            br.close();
            socket.close();
            serverSocket.close();

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

3、Socket中实现对象的传递

传递对象信息需要序列化

方法:

ObjectOutputStream  oos = new  ObjectOutputStream(…);
oos.writeObject(…);

ObjectInputStream  ois = new  ObjectInputStream(…);
Object = ois.readObject();

实例:

创建用户类

public class User implements Serializable {
    private String name;

    private String password;

    private String gender;

    private String phone;

    private String message;
//.......有参,无参
//.......set/get/方法
}

创建服务端

public class ServerSocketTcp {
    public static void main(String[] args) {
        try {
            //建立客户端serverSocket连接,指定服务器的位置为本机以及端口为8080
            ServerSocket serverSocket = new ServerSocket(8080);
            System.out.println("*******************服务器端已启动*****************");
            //使用accept()方法等待客户端发起通信
            Socket socket = serverSocket.accept();
            //反序列化
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            //打开输出流
            OutputStream os = socket.getOutputStream();
            //获取客户信息,从输入流读取信息
            User user = (User)ois.readObject();
            String response = "";
            if("admin".equals(user.getName())  && "123456".equals(user.getPassword())){
                System.out.println("客户端登录成功");
                System.out.println("客户端的登录信息是:" + user);
                System.out.println("客户端发送的消息:" + user.getMessage());
                response = "客户端登录成功!允许访问服务器";
            }else{
                response = "登录失败!用户名或密码错误!";
            }
            //给客户端一个响应,即向输出流中写入信息
            os.write(response.getBytes(StandardCharsets.UTF_8));
            //关闭资源
            os.flush();
            os.close();
            ois.close();
            socket.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

创建客户端

public class ClientSocketTcp {
    public static void main(String[] args) {
        try {
            //建立客户端socket连接,指定服务器的位置为本机以及端口为8080
            Socket socket = new Socket("127.0.0.1",8080);
            System.out.println("******************客户端已连接********************");
            //打开输出流
            OutputStream os = socket.getOutputStream();
            //对象序列化
            ObjectOutputStream oos = new ObjectOutputStream(os);
            //
            BufferedReader bw = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //String request = "你好啊,服务器端,我这里是客户端";
            User user = new User("admin","123456","男","18037678296","你好,客户端申请登录");
            //向对象输出流中写入信息
            oos.writeObject(user);

            oos.flush();
            //接收服务器端的响应,即从输入流读取信息
            String line = null;
            String info = "";
            while ((line=bw.readLine())!=null){
                info += line;
            }
            System.out.println("客户端收到的信息:" + info);

            bw.close();
            oos.close();
            os.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("客户端连接到服务器端失败!");
        }
    }
}

4、多线程处理多请求

创建用户类

public class User1 implements Serializable {
    private String name;

    private String password;

    private String gender;

    private String phone;

    private String message;

    //.......有参,无参
    //.......set/get/方法
   }

将服务端接收回复内容写入线程中

public class LoginThread extends Thread{

    private Socket socket;
    public LoginThread(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run(){
        try {
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());

            OutputStream os = socket.getOutputStream();

            User user = (User)ois.readObject();
            String response = "";
            if("admin".equals(user.getName())  && "123456".equals(user.getPassword())){
                System.out.println("客户端登录成功");
                System.out.println("客户端的登录信息是:" + user);
                System.out.println("客户端发送的消息:" + user.getMessage());
                response = "客户端登录成功!允许访问服务器";
            }else{
                response = "登录失败!用户名或密码错误!";
            }

            os.write(response.getBytes(StandardCharsets.UTF_8));
            os.flush();
            os.close();
            ois.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

创建服务端

public class ServerSocketTcp {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(8080);
            System.out.println("******************服务端已启动********************");
            Socket socket = null;
            while (true){
                socket = serverSocket.accept();
                LoginThread loginThread = new LoginThread(socket);
                loginThread.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

创建客户端

public class ClientSocketTcp {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1",8080);
            System.out.println("******************客户端已连接********************");

            OutputStream os = socket.getOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(os);
            BufferedReader bw = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //String request = "你好啊,服务器端,我这里是客户端";
            User user = new User("root","123456","男","18037678296","你好,客户端申请登录");

            oos.writeObject(user);

            oos.flush();

            String line = null;
            String info = "";
            while ((line=bw.readLine())!=null){
                info += line;
            }
            System.out.println("客户端收到的信息:" + info);

            bw.close();
            oos.close();
            os.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("客户端连接到服务器端失败!");
        }
    }
}

可以创建多个客户端,但端口要与服务端相同,要不然会报错

TCPUDP
是否连接面向连接面向非连接
传输可靠性可靠不可靠
速度

二、基于UDP协议的Socket编程

1、基于UDP协议的Socket网络编程步骤

1、利用DatagramPacket 对象封装数据包

2、利用 DatagramSocket 发送数据包

3、利用DatagramSocket接收数据包

4、利用DatagramPacket 处理数据包

实例:

创建服务端

public class ServerSocketUdp {
    public static void main(String[] args) {

        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
        try {
            DatagramSocket socket = new DatagramSocket(9090);
            socket.receive(dp);

            String info = new String(bytes,0,bytes.length);

            System.out.println("客户端:" + info);


        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

创建客户端

public class ClinetSocketUdp {
    public static void main(String[] args) {
        String info = "你好,这里是客户端!";
        byte[] bytes = info.getBytes(StandardCharsets.UTF_8);
        try {
            InetAddress inetAddress = InetAddress.getByName("localhost");
            DatagramSocket socket = new DatagramSocket();
            DatagramPacket dp = new DatagramPacket(bytes,bytes.length,inetAddress,9090);
            socket.send(dp);

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值