基于Socket实现客户端与服务器的通信
客户端(Android设备)Java代码:
目标:向服务器192.168.1.139发送信息,信息内容为tensor(shape:1x1x12x23,可以自己改变发送信息内容),供服务器调用深度学习LSTM模型
Thread t1 = new Thread(new RunnableTask(tensor));
t1.start();
private class RunnableTask implements Runnable {
private float[] tensor;
public RunnableTask(float[] m) {
this.tensor = m;
}
@Override
public void run() {
Socket socket = new Socket();
try {
/* 指定Server的IP地址,此地址为局域网地址,如果是使用WIFI上网,则为PC机的WIFI IP地址
* 在ipconfig查看到的IP地址如下:
* Ethernet adapter 无线网络连接:
* Connection-specific DNS Suffix . : IP Address. . . . . . . . . . . . : 192.168.1.100
*/
InetAddress serverAddr = InetAddress.getByName("192.168.1.139");// TCPServer.SERVERIP
Log.d("forecast", "Client: 连接中Connecting...");
// 应用Server的IP和端口建立Socket对象
socket = new Socket(serverAddr, 51706);
String message = "---Test_Socket_Android(Window Num:"+tensor.length/23.0+")---";
Log.d("forecast", "Client: 发送中Sending: '" + message + "'");
// 将信息通过这个对象来发送给Server
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
// 把用户输入的内容发送给server
String toServer = Arrays.toString(tensor);
Log.d("forecast", "To server:'" + toServer + "'");
out.println(toServer);
out.flush();
// 接收服务器信息
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
// 得到服务器信息
String msg = in.readLine();
Log.d("forecast", "From server:'" + msg + "'");
// 在页面上进行显示
Log.d("forecast", "Success");
} catch(UnknownHostException e) {
Log.e("forecast", "192.168.1.139 is unkown server!");
} catch(Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
服务器端Java代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 测试Android客户端与PC服务器通过socket进行交互
* 服务器端:接收客户端的信息并回送给客户
* javac -encoding UTF-8 Server.java
* java Server
*/
public class Server implements Runnable {
public static final String SERVERIP = "192.168.1.139";
public static final int SERVERPORT = 51706;
public void run() {
try {
System.out.println("Server: 连接中Connecting...");
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// 等待接受客户端请求
Socket client = serverSocket.accept();
System.out.println("Server: 接收中Receiving...");
try {
//client.getOutputStream()方法返回一个OutputStream对象,用于将字节写入客户端。client.getInputStream()方法返回一个InputStream对象,用于从客户端读取字节。
// 接受客户端信息
BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
// 发送给客户端的消息
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(client.getOutputStream())),true);
System.out.println("Server: 准备读取");
String str = in.readLine(); // 读取客户端的信息
System.out.println("Server: 读取完毕");
if (str != null ) {
// 设置返回信息,把从客户端接收的信息再返回给客户端
out.println("Server has already received the information from client");
out.flush();
// 把客户端发送的信息保存到文件中
File file = new File ("D:\\monitor\\Fore_Normal_MoreToOne - BiLstm\\receive.txt");
FileOutputStream fops = new FileOutputStream(file);
byte [] b = str.getBytes();
for ( int i = 0 ; i < b.length; i++ )
{
fops.write(b[i]);
}
System.out.println("Server: 接收信息Received: '" + str + "'");
} else {
System.out.println("未接收任何信息Not receiver anything from client!");
}
} catch (Exception e) {
System.out.println("Server: Error 1");
e.printStackTrace();
} finally {
client.close();
System.out.println("Server: Done.");
}
}
} catch (Exception e) {
System.out.println("Server: Error 2");
e.printStackTrace();
}
}
public static void main(String [] args ) {
Thread desktopServerThread = new Thread(new Server());
desktopServerThread.start();
}
}
服务器端代码python实现(将接收信息输入模型,返回结果):
import re
import socket
import time
import sys
import threading
import numpy as np
import torch
from lstmModel import BilstmModel
from options import options
def deal(s, model_path):
missed = ''
strlist = re.findall(r'[-+]?([0-9]*\.[0-9]+)|[0-9]+', s)
strarray = np.array(strlist).astype(float)
print(len(strarray))
try:
variablex = torch.tensor(strarray, dtype=torch.float).reshape(1, 1, 12, 23)
Model = BilstmModel(input_size=options['input_size'],
hidden_size=options['hidden_size'],
num_layers=options['num_layers'],
num_keys=options['num_classes'])
model = Model.to(torch.device('cpu'))
model.load_state_dict(torch.load(model_path)['state_dict'])
# 测试模式
model.eval()
with torch.no_grad():
output = model(features=variablex)
missed = str(output.tolist()[0][0])
except:
print("Server : 数据不全,error")
return missed
def server():
# 获取本机电脑名
myname = socket.gethostname()
# 获取本机ip
myPC_IP = socket.gethostbyname(myname)
COD = 'utf-8'
# 需要内网IP
HOST = myPC_IP # 主机ip
# 服务器防火墙需要打开这个端口,允许访问
PORT = 51706 # 软件端口号
BUFSIZ = 1024
ADDR = (HOST, PORT)
SIZE = 50
tcpS = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建socket对象
print("Server: 连接中Connecting...")
tcpS.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 加入socket配置,重用ip和端口
tcpS.bind(ADDR) # 绑定ip端口号
tcpS.listen(SIZE) # 设置最大链接数
while True:
msg = ""
clientsocket, addr = tcpS.accept()
print("Server: 接收中...Receiving From IP,PORT:", addr, "...")
print("Server: 准备读取")
while True:
try:
data = clientsocket.recv(BUFSIZ) # 读取已链接客户的发送的消息
except Exception:
print("Server: 客户端连接断开Error1...", addr)
break
msg += data.decode(COD)
if len(data) < BUFSIZ:
print("Server: 读取完毕")
break
if len(msg) > 0:
print("Server: 客户端发送的内容:", msg)
fore = deal(msg, 'checkpoints/taobao_normal/taobao_normal_bestloss.pth')
try:
clientsocket.send(("Response from ip:" + HOST + ". Server has already received the information from client. The Total missed is " + fore).encode(COD)) # 发送消息给已链接客户端
print("Server: 成功回复客户端...", addr)
except:
print("Server: 客户端连接异常Error2...", addr)
else:
print("未接收任何信息Not receiver anything from client!", msg)
clientsocket.close() # 关闭客户端链接
print("Server: Done.\n\n\n")
tcpS.close()
thread = threading.Thread(target=server, name="ModelServer")
thread.start()