问题说明
本篇开门见山,在做机器学习项目时有时会遇到前后端的交互问题。以本地打码平台为例,在模型训练好之后前端是由java写的,模型则是由python完成,前后端的交互实际上就是前后端两个程序所在线程的交互,所以将python所在线程实现ServerSocket,Java线程实现Socket则可实现交互。
Python:
import socket
import sys
import threading
import json
import numpy as np
from train.predict import Predict
from utils.to_gray import img_to_gray
def main():
predict = Predict()
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 12345
serversocket.bind((host, port))
serversocket.listen(5)
# 获取本地服务器的连接信息
myaddr = serversocket.getsockname()
print("服务器地址:%s" % str(myaddr))
# 循环等待接受客户端信息
while True:
# 获取一个客户端连接
clientsocket, addr = serversocket.accept()
try:
clientsocket.settimeout(50)
print("连接地址:%s" % str(addr))
# 获得一个连接,然后开始循环处理这个连接发送的信息
while True:
#vgg识别
image_path = "G:\\java\\testcode.png"
img_to_gray(image_path)
lable = predict.predict_img(image_path)
clientsocket.send(lable.encode("utf-8"))
print("识别结果:",lable)
break # 退出连接监听循环
except socket.timeout:
print("time out")
Java:
这里我把Code封装成了类,使用时实例化为HttpServlet的一个私有属性,在doGet/doPost中直接调用code.send()即可。
package servlet;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
public class Code {
String HOST = "192.168.199.1";
int PORT = 12345;
PrintStream out = null;
// 访问服务进程的套接字
Socket socket = null;
byte[] bytes = new byte[1024];
public Code(){
try {
// 初始化套接字,设置访问服务的主机和进程端口号,HOST是访问python进程的主机名称,可以是IP地址或者域名,PORT是python进程绑定的端口号
socket = new Socket(HOST,PORT);
// 获取输出流对象
OutputStream os = socket.getOutputStream();
out= new PrintStream(os);
}catch (Exception e){
e.printStackTrace();
}
}
public void send(String str){
try {
// 发送内容
out.print(str);
// 告诉服务进程,内容发送完毕,可以开始处理
out.print("over");
out.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
public String receive(){
try {
// 获取服务进程的输入流
//输入流
InputStream inputStream =socket.getInputStream();
int len = inputStream.read(bytes);
String str = new String(bytes,0,len);
return str;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}