zoukankan      html  css  js  c++  java
  • Socket的应用案例

    java提供网络功能的四大类
    1、InetAddress :用于标识网络上的硬件资源。
    2、URL:统一资源定位符,通过URL可以直接读取和写入网络上的数据。
    3、Socket:使用TCP协议实现网络通信的Socket相关类
    4、Datagram:使用UDP协议,将数据保存到数据报中,通过网络进行通讯。

    InetAddress的使用
    public static void main(String[] args) throws Exception {
    //获取本机的InetAddress实例
    InetAddress address = InetAddress.getLocalHost();
    //根据机器名字获取InetAddress的实例
    address=InetAddress.getByName("计算机名字");

    address.getHostName();//计算机名字
    address.getHostAddress();//IP地址
    address.getAddress();//字节数组形式的IP地址
    }

    URL的使用
    public static void main(String[] args) throws Exception {
    //创建一个url实例
    URL url = new URL("https://www.baidu.com");
    //创建子URL实例
    URL url2 = new URL(url, "/login.html?pw=北风");

    url.getProtocol();//协议
    url.getHost();//主机
    url.getPort();//端口号
    url.getPath();//文件路径
    url.getFile();//文件名
    url.getRef();//相对路径
    url.getQuery();//查询条件
    }
    URL的读取数据资源
    public static void main(String[] args) throws Exception {
    URL url =new URL("www.baidu.com");
    //通过openStream()方法获取URL对象所表示资源的字节输入流。
    InputStream is = url.openStream();
    //将字节流转换成字符流
    InputStreamReader isr = new InputStreamReader(is);
    //为字符流添加缓冲
    BufferedReader br = new BufferedReader(isr);

    //读取数据
    String info = null;
    if((info = br.readLine())!=null){
    System.out.println("读取的数据为:"+ info);
    }
    //关闭资源
    br.close();
    isr.close();
    is.close();
    }

    基于TCP协议实现网络通信
    客户端Socket类
    服务器端 ServerSocket 类

    步骤:1.建立服务器端倾听;2.客户端创建socket向服务器端发送请求;3.服务器端等待并接受连接请求,然后创建socket连接;4.服务器端与客户端通过IO流进行通讯;5.关闭两端的socket通信。

    服务器端:create --bind --listen--accept--recv/send--close
    1.创建ServerSocket对象,绑定监听端口;
    2.通过accept()方法监听客户端请求;
    3.建立连接后,通过输入流读取客户端发送的请求信息;
    4.通过输出流向客户端发送响应信息;
    5.关闭资源。
    客户端:create------- conncet------send/recv------close.
    1.创建Socket对象,绑定服务器地址和端口号;
    2.建立连接后通过输出流向服务器端发送请求信息;
    3.通过输入流获取服务器端响应的信息;
    4.关闭相关管资源。

    TCP代码展示
    客户端的 TCPServer.java
    public static void main(String[] args) {
    //1.创建服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口。
    ServerSocket serverSocket = new ServerSocket(8888);

    //2.调用accept()方法开始监听,等待客户端的连接
    System.out.println("***服务器即将启动,等待客户端的连接****");
    Socket socket = serverSocket.accept();//使之处于阻塞状态,等待客户端连接

    //3.获取输入流,并获取客户端的登录信息。
    InputStream is = socket.getInputStream();//字节输入流(用户登录信息)

    //读取对象
    ObjectInputStream ois = new ObjectInputStream(is);
    User vo = (User)ois.readObject();
    System.out.println(vo);

    //读取字符串
    //InputStreamReader isr = new InputStreamReader(is);//字符流转换成字节流,提高效率。
    //BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲
    //String info=null;
    //while ((info = br.readLine())!=null) {
    // System.out.println("我是服务器,客户端说:"+info);
    //}

    socket.shutdownInput();//关闭输入流

    //4.获取输出流,相应客户端请求
    OutputStream os = socket.getOutputStream();
    PrintWriter pw = new PrintWriter(os);//包装为打印流
    pw.write("您好!");
    pw.flush();//将缓冲输出

    //5.关闭资源
    pw.close();
    os.close();
    //br.close();
    //isr.close();
    is.close();
    socket.close();
    serverSocket.close();
    }

    服务器端 TCPClient.java
    public static void main(String[] args) {
    //1.创建客户端Socket,指定服务器地址和端口
    Socket socket = new Socket("localhost", 8888);

    //2.获取输出流,向服务器端发送消息
    OutputStream os = socket.getOutputStream();//字节输出流

    //3.对象方式传输
    ObjectOutputStream oos = new ObjectOutputStream(os);//传递对象
    User vo = new User("admin", "123456");
    oos.writeObject(vo);//序列化
    oos.flush();

    //3.字符串方式传递
    //PrintWriter pw = new PrintWriter(os);//将输出流包装为打印流
    //pw.write("用户名:admin,密码:123");
    //pw.flush();//刷新缓存,像服务器端输出信息

    socket.shutdownOutput();//关闭输出流

    //4.获取输入流,并读取服务器端的响应信息
    InputStream is= socket.getInputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    String info=null;
    while ((info = br.readLine())!=null) {
    System.out.println("我是客户端,服务端说:"+info);
    }
    socket.shutdownInput();//关闭输入流

    //5.资源关闭
    br.close();
    is.close();
    //pw.close();
    os.close();
    socket.close();
    }

    可以使用多线程实现服务器与多客户端之间的通信。
    循环调用 accept()方法。
    ServerThread.java,继承Thread类
    //和本线程相关的socket
    Socket socket = null;

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

    //线程执行的操作,响应客户端的请求
    public void run(){
    //3.获取输入流,并获取客户端的登录信息。
    InputStream is = socket.getInputStream();//字节输入流(用户登录信息)
    InputStreamReader isr = new InputStreamReader(is);//字符流转换成字节流,提高效率。
    BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲

    String info=null;
    while ((info = br.readLine())!=null) {
    System.out.println("我是服务器,客户端说:"+info);
    }

    socket.shutdownInput();//关闭输入流

    //4.获取输出流,相应客户端请求
    OutputStream os = socket.getOutputStream();
    PrintWriter pw = new PrintWriter(os);//包装为打印流
    pw.write("您好!");
    pw.flush();//将缓冲输出

    //5.关闭资源(略)
    }

    基于UDP协议实现网络通信
    DatagramPacket:标示数据包
    DatagramSocket:进行端到端的通信

    服务器端:
    1.创建DatagramSocket,指定端口号;
    2.创建DatagramPacket;
    3.接收客户端发送的数据信息;
    4.读取数据,并向客户端相应数据;
    5.关闭资源。
    客户端:
    1.定义发送信息;
    2.创建DatagramPacket,包含将要发送的信息
    3.创建DatagramSocket;
    4.发送数据,并接收服务器端数据。
    5.关闭资源。

    UDP代码展示
    UDPServer.java
    public static void main(String[] args) throws Exception {
    /* 服务器端接收客户端信息 */

    //1.创建服务器端的,指定端口号
    DatagramSocket datagramSocket = new DatagramSocket(8800);

    //2.创建数据包,用于接收客户端发送的数据
    byte data[] = new byte[1024];//创建字节数组,指定接收数据报的大小
    DatagramPacket packet = new DatagramPacket(data, data.length);

    System.out.println("***服务器端已经启动,等待客户端****");

    //3.接收客户端发送的数据
    datagramSocket.receive(packet);//此方法在接受到数据报之前会一直阻塞;

    //4.读取数据
    String info = new String(data, 0, packet.getLength());
    System.out.println("我是服务器,客户端说:"+info);


    /* 服务端想客户端响应数据 */

    //1.指定客户端地址、端口号、数据
    InetAddress inetAddress = packet.getAddress();
    int port = packet.getPort();
    byte data2[] = "欢迎您!".getBytes();

    //2.创建数据包,包含响应信息
    DatagramPacket datagramPacket2 = new DatagramPacket(data2, data2.length, inetAddress, port);

    //3.响应客户端
    datagramSocket.send(datagramPacket2);

    //4.关闭资源信息
    datagramSocket.close();
    }
    UDPClient.java
    public static void main(String[] args) throws Exception {
    /*向服务器端发送数据*/

    //1.定义服务器地址、端口号、数据
    InetAddress address = InetAddress.getByName("localhost");
    int port=8800;
    byte data[] = "用户名:admin,密码:123".getBytes();

    //2.创建一个数据包,包含数据信息
    DatagramPacket datagramPacket = new DatagramPacket(data, data.length, address, port);

    //3.创建 DatagramSocket 对象
    DatagramSocket datagramSocket = new DatagramSocket();

    //4.向服务器端发送数据包
    datagramSocket.send(datagramPacket);

    /*接收服务器端数据*/
    //1.创建数据包,用于接收服务器端响应的数据
    byte data2[] = new byte[1024];
    DatagramPacket datagramPacket2 = new DatagramPacket(data2, data2.length);

    //2.接收服务器端接收的数据
    datagramSocket.receive(datagramPacket2);

    //3.读取数据
    String reply = new String(data2, 0, datagramPacket2.getLength());
    System.out.println("我是客户端,服务器端说:"+reply);

    //4.关闭资源
    datagramSocket.close();
    }


    面试
    1:tcp和udp的区别
    TCP:是面向连接的流传输控制协议,具有高可靠性,确保传输数据的正确性,有验证重发机制,因此不会出现丢失或乱序。
    UDP:是无连接的数据报服务,不对数据报进行检查与修改,无须等待对方的应答,会出现分组丢失、重复、乱序,但具有较好的实时性,UDP段结构比TCP的段结构简单,因此网络开销也小。
    2:怎么检测socket是不是断开了?
    设置心跳包,设置socket为非阻塞,这样,当断线后,select、send、recv等会返回-1,表示断线

  • 相关阅读:
    记录一下自己写PHP程序时走过的一些坑
    自己写了一个TCP攻击测压平台
    Centos 7x 安装 Telegram MTproxy代理【完美可用】
    "@阅后即焚"上线了!
    小白的机器学习坑3:粗大的安装CUDA
    小白的机器学习坑2:nvidia驱动的安装
    小白的机器学习坑1:ubuntu 18.04的安装
    小白的linux学习笔记9:安装nodejs和gitbook
    小白的linux笔记11:放弃gitbook,转战Sphinx
    小白的linux学习笔记10:安装nginx和第一个网页
  • 原文地址:https://www.cnblogs.com/qypx520/p/6483469.html
Copyright © 2011-2022 走看看