• 网络编程之Socket & ServerSocket


    网络编程之Socket & ServerSocket

    Socket:网络套接字,网络插座,建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;socket用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。

    1、客户端Socket类

    此类实现客户端套接字

    构造方法

    构造方法 作用
    Socket(String host, int port) 创建一个套接字,并将其连接到指定的主机的指定端口上

    参数

    String host:服务器主机的名称、服务器的IP地址

    int port:服务器的端口号

    成员方法

    成员方法 作用
    OutputStream getOutputStream() 返回此套接字的字节输出流
    InputStream getInputStream() 返回此套接字的字节输入流
    void close() 关闭此套接字

    实现步骤

    • 创建一个客户端对象Socket,构造方法中绑定服务器的IP地址,端口号
    • 使用Socket对象中的方法getOutputStream获取网络字节输出流OutputStream对象
    • 使用网络字节输出流OutputStream对象的方法write,给服务器发送信息
    • 使用Socket对象的方法getInputStream获取网络字节输入流InputStream对象
    • 使用网络字节输入流InputStream的方法read读取服务器返回的信息
    • 调用close方法关闭套接字,释放资源

    注意

    • 当客户端与服务器交互时,必须使用Socket中提供的网络流,不能使用自己创建的流对象
    • 当创建客户端Socket对象时,就会去请求服务器,和服务器进行三次握手建立TCP连接。如果此时服务器没有启动,就会抛出异常,否则就可以进行交互了。

    TCP的客户端代码

    package cn.zhuobo.day15.aboutSocket;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class ClientSocket {
        public static void main(String[] args) throws IOException {
            Socket so = new Socket("127.0.0.1", 8868);
            OutputStream outputStream = so.getOutputStream();
            outputStream.write("你是他妈的服务器吗".getBytes());
    
            InputStream inputStream = so.getInputStream();
            byte[] bytes = new byte[1024];
            int len = inputStream.read(bytes);
            System.out.println(new String(bytes, 0, len));
    
            so.close();
    
        }
    }
    

    2、服务器套接字ServerSocket

    此类实现服务端套接字

    构造方法

    构造方法 作用
    ServerSocket(int port) 创建一个服务器套接字,并绑定到特定的端口号上

    成员方法

    成员方法 作用
    Socket accept() 监听并接收此套接字的连接,用这个方法获取请求连接的客户端Socket对象
    void close() 关闭此套接字

    服务器ServerSocket的实现过程

    • 创建服务器ServerSocket对象,并指定需要的端口号
    • 使用ServerSocket对象的accept方法获取请求的客户端Socket对象
    • 使用获取到的Socket对象的getInputStream方法,获取网络字节输入流InputStream对象
    • 使用网络字节输入流InputStream对象的read方法,读取客户端发送的数据
    • 使用获取到的Socket对象的getOutputStream方法,获取网络字节输出流OutputStream对象
    • 使用网络字节输出流OutputStream队形的write方法,给客户端写回数据
    • 释放资源,Socket对象和ServerSocket对象依次调用close方法

    服务器ServerSocket代码

    package cn.zhuobo.day15.aboutSocket;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class MyServerSocket {
        public static void main(String[] args) throws IOException {
            ServerSocket server = new ServerSocket(8868);
            Socket so = server.accept();
    
            InputStream inputStream = so.getInputStream();
            byte[] bytes = new byte[1024];
            int len = inputStream.read(bytes);
            System.out.println(new String(bytes, 0, len));
    
            OutputStream outputStream = so.getOutputStream();
            outputStream.write("我是他么的服务器,你是他么的客户端吗".getBytes());
            so.close();
            server.close();
        }
    }
    

    这样就客户端和服务器就实现了通信

    3、文件上传案例

    文件的上传其实就是本地硬盘的文件复制到服务器的硬盘

    注意

    客户端、服务器和本地进行文件读写,使用的是自己创建道德字节流对象(本地流)

    客户端和服务器之间的文件读写,使用的是Socket提供的字节流对象(网络流)

    Client代码

    package cn.zhuobo.day15.fileUploadPractise;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class TCPClient {
        public static void main(String[] args) throws IOException {
            FileInputStream fis = new FileInputStream("/home/zhuobo/Desktop/dir/1.png");
            Socket socket = new Socket("127.0.0.1", 8888);
            OutputStream outputStream = socket.getOutputStream();
    
            byte[] bytes = new byte[1024];
            int len = 0;
            while((len = fis.read(bytes)) != -1) {
                outputStream.write(bytes, 0, len);
            }
    
            socket.shutdownOutput();
    
            InputStream inputStream = socket.getInputStream();
            while((len = inputStream.read(bytes)) != -1) {
                System.out.println(new String(bytes, 0, len));
            }
    
            fis.close();
            socket.close();
    
        }
    }
    

    Server代码

    package cn.zhuobo.day15.fileUploadPractise;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Random;
    
    public class TCPServer {
        public static void main(String[] args) throws IOException {
            ServerSocket server = new ServerSocket(8888);
    
            while(true) {
                Socket socket = server.accept();
    
                new Thread(new Runnable() {// 每次侦听到有客户端程序要上传文件,也就是accept方法后就开启一个新的线程,提高效率
                    @Override
                    public void run() {
                        try {// 因为run方法没有声明抛出异常,因此只能使用try catch处理异常
                            InputStream inputStream = socket.getInputStream();
    //                        如果不存在这个目录就创建
                            File file = new File("/home/zhuobo/Desktop/uploads");
                            if(!(file.exists())) {
                                file.mkdirs();
                            }
                            // 文件命名的规则
                            String filename = "/" + System.currentTimeMillis() + (new Random().nextInt(99999)) + ".png";
    
                            FileOutputStream fos = new FileOutputStream(file + filename);
    
                            byte[] bytes = new byte[1024];
                            int len = 0;
                            while((len = inputStream.read(bytes)) != -1) {
                                fos.write(bytes, 0, len);
                            }
    
                            socket.getOutputStream().write("文件上传成功!".getBytes());
    
                            fos.close();
                            socket.close();
                        }catch (IOException e) {
                            System.out.println(e);
                        }
                    }
                }).start();
            }
            //server.close();
        }
    }
    
    
  • 相关阅读:
    嵌入式根文件系统的制作和挂载【转】
    嵌入式Linux内核制作【转】
    Linux按键驱动程序设计--从简单到不简单【转】
    Linux设备驱动工程师之路——内核链表的使用【转】
    linux设备驱动归纳总结(十三):1.触摸屏与ADC时钟【转】
    linux设备驱动归纳总结(十二):简单的数码相框【转】
    linux设备驱动归纳总结(十一):写个简单的看门狗驱动【转】
    linux设备驱动归纳总结(十):1.udev&misc【转】
    linux设备驱动归纳总结(九):1.platform总线的设备和驱动【转】
    linux设备驱动归纳总结(八):4.总线热插拔【转】
  • 原文地址:https://www.cnblogs.com/zhuobo/p/10662061.html
Copyright © 2020-2023  润新知