問題說明
本篇開門見山,在做機器學習項目時有時會遇到前後端的交互問題。以本地打碼平臺爲例,在模型訓練好之後前端是由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;
}
}
}