美文网首页
三、Socket简解

三、Socket简解

作者: 小鱼你好 | 来源:发表于2022-03-25 14:29 被阅读0次

    Socket是应用层与TCP/IP协议族通信的中间软件抽象层,他是一组接口,把复杂的TCP/IP协议族隐藏在Socket接口后面,用户使用Socket提供的接口即能实现连接远程机器-发送数据-接收数据-关闭连接-绑定端口-监听到达数据-在绑定的端口上接受来自远程机器的连接。Socket分为服务端ServerSocket和客户端Socket,建立连接时要分别创建对应的Socket实例。

    客户端Socket构造方法说明:

    Socket():创建一个新的未连接的Socket。
    Socket(Proxy proxy):使用指定的代理类型创建一个新的未连接的Socket。
    Socket(Sting dstName,int dstPort):使用指定的目标服务器IP地址和目标服务器端口号创建一个新的Socket。
    Socket(Sting dstName,int dstPort,InetAddress localAddress,int localPort):使用指定的目标主机、目标端口、本地地址和本地端口,创建一个新的 Socket。
    Socket(InetAddress localAddress,int localPort):使用指定的本地地址和本地端口,创建一个新的 Socket。
    Socket(InetAddress dstAddress,int dstPort,InetAddress localAddress,int localPort):使用指定的目标主机、目标端口、本地地址和本地端口,创建一个新的 Socket。
    其中,proxy为代理服务器地址,dstAddress为目标服务器IP地址,dstPort为目标服务器端口号,dstName为目标服务器主机名。

    Socket client=new Socket("192.168.1.23", 2012); 
    // 第一个参数是目标服务器的 IP 地址,2012 是目标服务器的端口号
    

    客户端Socket重要方法说明:

    public InputStream getInputStream():读出该Socket中的数据。
    public OutputStream getOutputStream():向Socke中写入数据。
    public synchronized void close():关闭该Socket。

    服务端ServiceSocket构造方法说明:

    ServiceSocket():构造一个新的未绑定的ServiceSocket。
    ServiceSocket(int port):构造一个新的ServiceSocket实例并绑定到指定端口,如果port为0,端口将由操作系统自动分配,此时进入队列的数目将被设置为50。
    ServiceSocket(int port,int backlog):构造一个新的ServiceSocket实例并绑定到指定端口,并且指定进入队列的数目,如果port为0端口号由系统分配。
    ServiceSocket(int port,int backlog,InetAddress localAddress):构造一个新的ServiceSocket实例并绑定到指定端口和指定地址,同时指定进入队列的数目,如果localAddress为null,则可以使用任意地址,如果port为0端口由系统分配。

    ServerSocket socketserver=new ServerSocket(2012); 
    // 2012 表示服务器要监听的端口号
    

    服务端ServiceSocket重要方法说明:

    public Socket accept():等待客户端Socket请求,直到链接被打开,该方法返回一个刚刚打开的连接的客户端Socket对象。
    public void close():关闭服务器Socket。
    Socket 一般有两种类型:TCP 套接字和 UDP 套接字。TCP 把消息分解成数据包并在接收端以正确的顺序把它们重新装配起来,TCP 还处理对遗失数据包的重传请求减少上层应用数据处理。UDP 不提供装配和重传请求这些功能,它只是向前传送信息包。上层的应用层必须确保消息是完整的,并且是以正确的顺序装配。

    TCP服务端工作流程:

    1,调用ServiceSocket(int port)创建一个ServiceSocket,并绑定到指定端口上。
    2,调用accept(),监听连接请求,如果客户端请求连接则接受连接返回通信套接字。
    3,调用Socket类的getOutputStream()和getInputStream()获取输出输入流开始网络数据的发送和接收。
    4,调用close()方法关闭套接字。

    // 创建一个 ServerSocket 对象 
    ServerSocket serverSocket = null;
    try {
     // TCP_SERVER_PORT 为指定的绑定端口,为 int 类型
     serverSocket = new ServerSocket(TCP_SERVER_PORT);
     // 监听连接请求
     Socket socket = serverSocket.accept();
     // 写入读 Buffer 中
     BufferedReader in = new BufferedReader(new 
     // 获取输入流
     InputStreamReader(socket.getInputStream()));
     // 放到写 Buffer 中
     BufferedWriter out = new BufferedWriter(new 
     // 获取输出流
     OutputStreamWriter(socket.getOutputStream()));
     // 读取接收信息,转换为字符串
     String incomingMsg = in.readLine() + System.getProperty("line.separator");
     // 生成发送字符串
     String outgoingMsg = "goodbye from port " + TCP_SERVER_PORT + 
     System.getProperty("line.separator");
     // 将发送字符串写入上面定义的 BufferedWriter 中
     out.write(outgoingMsg);
     // 刷新,发送
     out.flush();
     // 关闭
     socket.close();
    } catch (InterruptedIOException e) {
     // 超时错误
     e.printStackTrace();
     // IO 异常
    } catch (IOException e) {
     // 打印错误
     e.printStackTrace();
    } finally {
     // 判定是否初始化 ServerSocket 对象,如果初始化则关闭 serverSocket
     if (serverSocket != null) {
     try {
     serverSocket.close();
     } catch (IOException e) {
     e.printStackTrace();
     }
     }
    }
    

    TCP客户端工作流程:

    1,调用Socket()创建一个流套接字,并连接到服务端。
    2,调用Socket类的getOutputStream()和getInputStream()方法获取输出和输入流开始网络数据的发送和接收。
    3,调用close()方法关闭套接字。

    try {
     // 初始化 Socket,TCP_SERVER_PORT 为指定的端口,int 类型
     Socket socket = new Socket("localhost", TCP_SERVER_PORT);
     // 获取输入流
     BufferedReader in = new BufferedReader(new 
     InputStreamReader(socket.getInputStream()));
     // 生成输出流
     BufferedWriter out = new BufferedWriter(new
     OutputStreamWriter(socket.getOutputStream()));
     // 生成输出内容
     String outMsg = "TCP connecting to " + TCP_SERVER_PORT + 
     System.getProperty("line.separator"); 
     // 写入
     out.write(outMsg);
     // 刷新,发送
     out.flush();
     // 获取输入流
     String inMsg = in.readLine() + System.getProperty("line.separator");
     Log.i("TcpClient", "received: " + inMsg);
     // 关闭连接
     socket.close();
     } catch (UnknownHostException e) {
     e.printStackTrace();
     } catch (IOException e) {
     e.printStackTrace();
    }
    

    UDP 服务端工作的主要步骤:

    1,调用DatagramSocket(int port)创建一个数据报套接字,并绑定到指定端口上。
    2,调用DatagramPacket(byte[] buf,int length),建立一个字节数组以接收UDP包。
    3,调用DatagramSocket类的receive(),接收UDP包。
    4,关闭数据报套接字。

    // 接收的字节大小,客户端发送的数据不能超过 MAX_UDP_DATAGRAM_LEN 
    byte[] lMsg = new byte[MAX_UDP_DATAGRAM_LEN];
    // 实例化一个 DatagramPacket 类
    DatagramPacket dp = new DatagramPacket(lMsg, lMsg.length);
    // 新建一个 DatagramSocket 类
    DatagramSocket ds = null;
    try {
     // UDP 服务器监听的端口 
     ds = new DatagramSocket(UDP_SERVER_PORT);
     // 准备接收数据 
     ds.receive(dp);
    } catch (SocketException e) {
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    } finally {
     // 如果 ds 对象不为空,则关闭 ds 对象
     if (ds != null) {
     ds.close();
     }
    }
    

    UDP 客户端工作的主要步骤:

    1,调用DatagramSocket()创建一个数据包套接字。
    2,调用DatagramPacket(byte[]buf,int offset,int length,InetAddress address,int port),建立要发送的 UDP 包。
    3,调用 DatagramSocket 类的 send() 发送 UDP 包。
    4,关闭数据报套接字。

    // 定义需要发送的信息
    String udpMsg = "hello world from UDP client " + UDP_SERVER_PORT;
    // 新建一个 DatagramSocket 对象
    DatagramSocket ds = null;
    try {
     // 初始化 DatagramSocket 对象
     ds = new DatagramSocket();
     // 初始化 InetAddress 对象
     InetAddress serverAddr = InetAddress.getByName("127.0.0.1");
     DatagramPacket dp;
     // 初始化 DatagramPacket 对象
     dp = new Datagram
     Packet(udpMsg.getBytes(), udpMsg.length(), serverAddr, UDP_SERVER_PORT);
     // 发送
     ds.send(dp);
    } 
    // 异常处理
    // Socket 连接异常
    catch (SocketException e) { 
     e.printStackTrace();
    // 不能连接到主机
    }catch (UnknownHostException e) { 
     e.printStackTrace();
    // 数据流异常
    } catch (IOException e) { 
     e.printStackTrace();
    // 其他异常
    } catch (Exception e) { 
     e.printStackTrace();
    } finally {
     // 如果 DatagramSocket 已经实例化,则需要将其关闭
     if (ds != null) {
     ds.close();
     }
    }
    

    相关文章

      网友评论

          本文标题:三、Socket简解

          本文链接:https://www.haomeiwen.com/subject/xwurjrtx.html