当前位置: 首页 > article >正文

TCP流套接字编程

目录

1.ServerSocket API

2.Socket API

3实例1:显示

3.1服务器

3.1.1步骤

3.1.2代码

3.2.客户端

3.2.1步骤

3.2.2代码

3.3多线程

3.4用线程池调用任务

4.翻译服务器


1.ServerSocket API

ServerSocket 是创建TCP服务端Socket的API。

方法签名

方法说明

ServerSocket(int port)

创建一个服务端流套接字Socket,并绑定到指定端口

ServerSocket 方法:

方法签名

方法说明

Socket accept()

开始监听指定端口(创建时绑定的端口),有客户端连接后,返回一个服务端

Socket对象,并基于该Socket建立与客户端的连接,否则阻塞等待

voidclose()

关闭此套接字

2.Socket API

Socket 是客户端Socket,或服务端中接收到客户端建立连接(accept方法)的请求后,返回的服务端Socket。

不管是客户端还是服务端Socket,都是双方建立连接以后,保存的对端信息,及用来与对方收发数据的。Socket 构造方法:

方法签名

方法说明

Socket(String host, intport)

创建一个客户端流套接字

Socket

,并与对应

IP

的主机上,对应端口的进程建立连接

Socket 方法

方法签名

方法说明

InetAddress getInetAddress()

返回套接字所连接的地址

InputStream getInputStream()

返回此套接字的输入流

OutputStream getOutputStream()

返回此套接字的输出流

 

3实例1:显示

3.1服务器

3.1.1步骤

  1. 进行网络编程,第一步要准备好socket实例
  2. 启动服务器
    1. 由于Tcp有连接,要先建立连接
      1. accept相当于接电话,如果客户端没有建立连接,就会阻塞
      2. accept返回一个socket对象,成为clientSocket,后序和客户端沟通就是通过clientSocket完成
      3. serverSocket就接电话,业务交给clientSocket
  3. 实现连接方法--接下来处理请求和响应
    1. 循环处理每个请求然后响应
    2. 读取请求
    3. 根据请求计算响应
    4. 把响应返回给客户端
    5. 要关闭
  4. 实现计算响应的方法

3.1.2代码

public class TcpEchoSever {
    private ServerSocket serverSocket=null;
    public TcpEchoSever(int port) throws IOException {
        serverSocket=new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动");
        Socket clientSocket=serverSocket.accept();
        processConnect(clientSocket);
    }

    private void processConnect(Socket clientSocket) {
        System.out.printf("[%s:%d] 客户端连接!\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());

        try(InputStream inputStream=clientSocket.getInputStream()){
            try(OutputStream outputStream= clientSocket.getOutputStream()){
                Scanner scanner=new Scanner(inputStream);
                while(true){
                    if(!scanner.hasNext()){
                        System.out.printf("[%s:%d] 客户端断开连接\n",clientSocket.getInetAddress(),
                                clientSocket.getPort());
                        break;
                    }
                    String request=scanner.next();
                    String response=process(request);
                    PrintWriter printWriter=new PrintWriter(outputStream);
                    printWriter.println(response);
                    printWriter.flush();
                    System.out.printf("[%s:%d] rep:%s, resp: %s\n",
                            clientSocket.getInetAddress(),clientSocket.getPort(),request,response);

                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoSever tcpEchoSever=new TcpEchoSever(9090);
        tcpEchoSever.start();
    }
}

3.2.客户端

3.2.1步骤

  1. 进行网络编程,第一步要准备好socket实例
  2. 启动客户端
    1. 从控制台读取字符串
    2. 根据读取的字符串,构造请求,把请求发个服务器
    3. 从服务器读取响应,并解析
    4. 把结果显示在控制台上

3.2.2代码

public class TcpEchoClient {
   private Socket socket=null;
    public TcpEchoClient(String ServerIP, int SeverPort) throws IOException {
        socket=new Socket("127.0.0.1",9090);
    }
    public void start(){
        System.out.println("服务器连接成功");
        Scanner scanner=new Scanner(System.in);
        try(InputStream inputStream=socket.getInputStream()) {
            try(OutputStream outputStream=socket.getOutputStream()){
                while(true){
                    System.out.println("->");
                    String request=scanner.next();
                    PrintWriter printWriter=new PrintWriter(outputStream);
                    printWriter.println(request);
                    printWriter.flush();
                    Scanner respScanner=new Scanner(inputStream);
                    String response=respScanner.next();
                    System.out.printf("req: %s,resp: %s\n",request,response);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.3多线程

主线程循环调用accept,当客户端连接,让主线程创建新线程,由新线程负责对客户端若干请求,提供服务(新线程中while循环来处理请求),多线程是并发执行的(宏观上是同时执行),就是各自执行各自的,不会干扰(每个客户端要连接都要分配一个线程)

public void start() throws IOException {
    System.out.println("服务器启动");
    while(true){
        Socket clientSocket=serverSocket.accept();
        Thread t=new Thread(()->{
            processConnection(clientSocket);
        });
        t.start();
    }
}

3.4用线程池调用任务

 public void start() throws IOException {
        System.out.println("服务器启动");
        ExecutorService pool=Executors.newCachedThreadPool();
        while(true){
            Socket clientSocket=serverSocket.accept();
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    processConnect(clientSocket); 
                }
            });
        }
        
        
    }

4.翻译服务器

TcpDictServer继承TcpThreadPoolEchoServer,重写process方法

public class TcpDictServer extends TcpThreadPoolEchoServer{
    private HashMap<String,String> dict=new HashMap<>();
    public TcpDictServer(int port) throws IOException {
        super(port);

        //简单构造几个词
        dict.put("cat","小猫");
        dict.put("dog","小狗");
        dict.put("pig","小猪");
    }

    @Override
    public String process(String request) {
        return dict.getOrDefault(request,"当前词无法翻译");
    }

    public static void main(String[] args) throws IOException {
        TcpDictServer server=new TcpDictServer(9090);
        server.start();
    }
}


http://www.kler.cn/a/5815.html

相关文章:

  • SQLite 命令
  • Flink-CDC 全面解析
  • 用c实现C++类(八股)
  • 简聊MySQL的顺序读写和随机读写
  • 51单片机(一) keil4工程与小灯实验
  • 自动化测试脚本实践:基于 Bash 的模块化测试框架
  • Spark sql怎么使用Kafka Avro序列化器
  • 阿里云高级技术专家林立翔:基于阿里云弹性GPU服务的神龙AI加速引擎,无缝提升AI训练性能
  • 每日学术速递4.3
  • React Native开发环境搭建-Windows平台
  • IT知识百科:什么是访问控制列表ACL?
  • @Lookup与@Bean@Scope获取原型实例,谁更胜一筹
  • gcc在Linux下如何运行一个C/C++程序
  • [致敬未来的攻城狮计划 1] 使用 “FSP Configuration”(FSP 配置)透视配置器设置运行环境
  • 2023年详解MySQL 开发规范
  • 指令操作码
  • python-实验报告-3
  • Nacos(Config)配置中心源码分析-02
  • 表和索引的并行度问题
  • 杂记——idea VM设置(idea启动缓慢,JVM部分参数解释,重启Idea)
  • 遗传算法(Genetic Algorithm,GA)
  • 交友项目【基础环境搭建】
  • 压缩器简介与实现
  • 炼钢厂VR职业技能实训软件,提高员工学习效率和掌握技能速度
  • 重置Win10电脑
  • Java中函数形参中`...`的作用