Java使用Socket实现进程间的通信

本章要实现两个进程之间的通信也是微服务的一些底层原理

需要的知识技能

  1. java基础
  2. Socket
  3. IO
  4. TCP,HTTP协议
  5. 反射

先创建第一个项目为服务项目

Serviec层写的是要被调用类,分别为借口和实现类

ServerBoot是Server的main函数

service的接口

package com.yunhe.server.service;

/**
 * class
 *
 * @author 知识快递
 * @date 2018年12月20日
 */
public interface IorderService {

    String getOrder(int orderId,String name);

    String getOrderName(String name);
}

Service的实现类,第二个方法本章没有用到

package com.yunhe.server.service.impl;

import com.yunhe.server.service.IorderService;

/**
 * class
 *
 * @author 知识快递
 * @date 2018年12月20日
 */
public class OrderService implements IorderService {

    @Override
    public String getOrder(int orderId, String name) {

        return "订单号:"+orderId+",订单名称:"+name;
    }

    @Override
    public String getOrderName(String name) {
        return "订单名称:"+name;
    }
}

ServerBoot的内容

package com.yunhe.server;

import java.io.IOException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;

/**
 * class
 *
 * @author 知识快递
 * @date 2018年12月20日
 */
public class ServerBoot {

    public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = new ServerSocket(8080);
        String requestdata = "";
        while (true) {
            Socket socketServer = serverSocket.accept();
            byte[] b = new byte[1];
            while (socketServer.getInputStream().read(b) != -1) {
                requestdata = requestdata + new String(b);
            }
            System.out.println("从客户端接收的数据:" + requestdata);
//            以"/r/n"为约定分割
            String[] split = requestdata.split("/r/n");
//            将数组的内容解码
            String packageName = split[0];
            String className = split[1];
            String method = split[2];
            String argVal = split[3];

            Class<?> classObj = null;
            try {
//                获取的包和类名找到本地的利用反射实例化
                classObj = Class.forName(packageName + "." + className);
                Method returnMethod = classObj.getMethod(method, String.class);
                String result = (String) returnMethod.invoke(classObj.newInstance(), argVal);
                System.out.println("返回给客户端的结果:"+result);
                socketServer.getOutputStream().write(result.getBytes(Charset.forName("UTF-8")));
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }
}

 

下面写客户端的内容

客户端和服务端接口基本上一样只是增加了SocketUtil的封装类

接口要和服务端定义的一样

package com.yunhe.client.service;

/**
 * class
 *
 * @author 知识快递
 * @date 2018年12月20日
 */
public interface IorderService {

/**
 * 服务端地址
  */
    String url = "127.0.0.1";

    /**
     * 远程端口
     */
    int port = 8080;

    /**
     * 远程的包名 /r/n是分割协议
     */
    String packageName = "com.yunhe.server.service.impl/r/n";

    String getOrder(Integer orderId, String name);

    String getOrderName(String name);
}

 

实现类为了规范把把名称改成了OrderServiceImpl

package com.yunhe.client.service.impl;

import com.yunhe.client.service.IorderService;
import com.yunhe.client.util.SocketUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * class
 *
 * @author 知识快递
 * @date 2018年12月20日
 */
public class OrderServiceImpl implements IorderService {

    @Override
    public String getOrder(Integer orderId, String name) {

//      把参数依次装到一个List里面
        List<String> argList = new ArrayList();
        argList.add(orderId.toString());
        argList.add(name);
        return SocketUtil.getSocket(url, port, packageName, argList);
    }

    @Override
    public String getOrderName(String name) {
        return "订单名称:" + name;
    }
}

封装Socket的类

package com.yunhe.client.util;

import java.io.IOException;
import java.net.Socket;
import java.util.List;

/**
 * class
 *
 * @author 知识快递
 * @date 2018年12月20日
 */
public class SocketUtil {

    public static String getSocket(String url, int port, String packageName, List<String> argList) {

        String reponseData = "";

        try {
            Socket client = new Socket(url, port);
//            获取服务端的 类 方法 和参数类型
            String className = "OrderServiceImpl/r/n";
            String method = "getOrderName/r/n";
//            依次写入这四个参数
            client.getOutputStream().write(packageName.getBytes());
            client.getOutputStream().write(className.getBytes());
            client.getOutputStream().write(method.getBytes());
//            遍历方法的参数
            for ( String argList1 : argList){

                client.getOutputStream().write(argList1.getBytes());
            }

            client.shutdownOutput();
//            获取服务器返回来的值
            byte[] b = new byte[1];
            while (client.getInputStream().read(b) != -1) {
                reponseData = reponseData + new String(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return reponseData;
    }
}

最后的是客户端的main函数

package com.yunhe.client;

import com.yunhe.client.service.impl.OrderServiceImpl;

/**
 * class
 *
 * @author 知识快递
 * @date 2018年12月20日
 */
public class ClientBoot {

    public static void main(String[] args) {
        new OrderServiceImpl().getOrder(1,"Socket");
    }
}

现在终于完成了来看成果吧

要先启动服务端

  • 0
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值