zoukankan      html  css  js  c++  java
  • 廖雪峰Java13网络编程-1Socket编程-2TCP编程

    1. Socket

    在开发网络应用程序的时候,会遇到Socket这个概念。
    Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据传输到网络。

    Socket/TCP/部分IP都是由操作系统提供的。不同的编程语言只是提供了对操作系统调用的加单封装,例如Java提供的几个Socket相关的类就封装了操作系统提供的接口。
    为什么需要Socket?
    因为仅仅通过IP地址进行通信还不够,同一台计算机同一时间会运行多个网络程序。当计算机收到一个数据包的时候,只有IP地址是没法判断应该发送给哪个应用程序的,所以操作系统抽象出Socket接口。每个应用程序需要对应不同的Socket,可以把Socket简单理解为IP地址+端口号。
    端口号是操作系统分配的,是在0-65535之间的数字

    • <1024是特权端口,需要管理员权限
    • >1024的端口可以由任意应用程序打开

    2. Socket使用

    Socket编程模型需要实现服务器端与客户端,因为2个应用程序通信的时候不仅需要对方的IP,还需要知道对方的端口号。所以服务器端必须先固定一个端口号,例如80。客户端在发起请求的时候,会直接请求80端口,同时告知自己的端口,这样双方就可以通过Socket进行通信了。
    客户端的编程:

        Socket sock = new Socket(InetAddress,port);//连接到远程服务器的指定端口
        InputStream in = sock.getInputStream();//获取到输入和输出流
        OutputStream out = sock.getOutputStream();    
        //读写字节流
    

    服务器端:

        ServerSocket ss = new ServerSocket(port); //监听指定端口号
        Socket sock = ss.accept();
        InputStream in = sock.getInputStream();
        OutputStream out = sock.getOutputStream();
        //读写字节流
    

    TCPClient.java

    import java.io.*;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.nio.charset.StandardCharsets;
    
    public class TCPClient {
        public static void main(String[] args) throws IOException{
            InetAddress addr = InetAddress.getLoopbackAddress(); //获取本机的InetAddress,通常是127.0.0.1
            try(Socket sock = new Socket(addr,9090)){ //打开远程连接
                try(BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream(),StandardCharsets.UTF_8))){//BufferedReader类就是一个包装类,它可以包装字符流,将字符流放入缓存里,到缓存满了或者执行flush的时候,再读入内存,可以提交读的效率。
                    try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(),StandardCharsets.UTF_8))){
                        writer.write("time
    ");
                        writer.flush();//强制把缓存区的内容发送出去
                        String resp = reader.readLine();
                        System.out.println("Response:"+resp);
                    }
                }
            }
        }
    }
    

    TCPServer.java

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.nio.charset.StandardCharsets;
    import java.time.LocalTime;
    
    public class TCPServer {
        public static void main(String[] args) throws Exception{
            ServerSocket ss = new ServerSocket(9090);
            System.out.println("TCP Server ready:");
            Socket sock = ss.accept();
            try(BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream(),StandardCharsets.UTF_8))){
                try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(),StandardCharsets.UTF_8))){
                    String cmd = reader.readLine(); //获取客户端传过来的数据
                    if("time".equals(cmd)){
                        writer.write(LocalTime.now()+"
    ");
                        writer.flush();
                    }
                }
            }
            sock.close();
            ss.close();
        }
    }
    

    先运行服务器端,再运行客户端

    3. 总结:

    TCP编程模型:

    • 客户端使用Socket(InetAddress,port)打开Socket
    • 服务器用ServerSocket监听端口
    • 服务器用accept接收连接并返回Socket
    • 双方通过Socket打开InputStream/OutputStream读写数据
    • flush()用于强制输出缓冲期
  • 相关阅读:
    vim编辑swap file
    fork: retry: Resource temporarily unavailable 解决方案
    扫描目录下的文件并拼接在一起
    linux 下批量创建文件夹
    存储过程批量插入表数据
    多用户登录系统操作流程——Python多线程
    触发器报错“Not allowed to return a result set from a trigger”的解决方案
    window + anaconda + python3.6 + dlib
    查看Ubantu磁盘信息
    numpy和tensorflow中矩阵乘法的区别
  • 原文地址:https://www.cnblogs.com/csj2018/p/11143363.html
Copyright © 2011-2022 走看看