欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

利用Socket进行Java与Python的通信

程序员文章站 2022-03-24 11:35:55
...

Python端

import socket
import sys
import threading
import json
import numpy as np

def main():

    # 创建服务器套接字
    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()
        print("连接地址:%s" % str(addr))

        try:
            #为每一个请求开启一个处理线程
            t = ServerThreading(clientsocket)
            t.start()
            pass
        except Exception as identifier:
            print(identifier)
            pass
        pass
    serversocket.close()
    pass

class ServerThreading(threading.Thread):

    def __init__(self,clientsocket,recvsize=1024*1024,encoding="utf-8"):
        threading.Thread.__init__(self)
        self._socket = clientsocket
        self._recvsize = recvsize
        self._encoding = encoding
        pass

    def run(self):
        print("开启线程.....")
        try:
            #接受数据
            msg = ''
            while True:
                # 从Java端读取recvsize个字节
                rec = self._socket.recv(self._recvsize)

                # 解码成字符串
                msg += rec.decode(self._encoding)
                print("解码后数据:")
                print(msg)

                # 文本接受是否完毕,因为python socket不能自己判断接收数据是否完毕
                # 所以需要自定义协议标志数据接受完毕
                if msg.strip().endswith('over'):
                    msg=msg[:-4]
                    break

            # 将字符串解析成JSON格式数据
            re = json.loads(msg)
            print("解析成JSON数据:")
            print(re)
            
            # 修改JSON数据并转换成字符串
            re["content"] = "world"
            sendmsg = json.dumps(re)
            print("修改JSON数据并发送:")
            print(sendmsg)

            # 发送字符串数据给Java端
            self._socket.send(("%s"%sendmsg).encode(self._encoding))
            pass
        except Exception as identifier:
            self._socket.send("500".encode(self._encoding))
            print(identifier)
            pass
        finally:
            self._socket.close() 
        print("任务结束.....")
        
        pass

    def __del__(self):
        
        pass
if __name__ == "__main__":
    main()

Java端

package cn.edu.xxx.computer.XXX.socket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.io.*;
import java.net.Socket;
import java.util.logging.Logger;

public class PythonSocket {

    public PythonSocket() {
    }

    public Object remoteCall(String content) {
        String HOST = "192.168.219.1";
        Integer PORT = 12345;
        Logger log = Logger.getLogger(this.getClass().getName());
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("content", content);
        String str = jsonObject.toJSONString();
        System.out.println("发送内容(JSONObject):" + jsonObject);
        System.out.println("发送内容(String):" + str);
        // 访问服务进程的套接字
        Socket socket = null;
        // List<Question> questions = new ArrayList<>();
        log.info("调用远程接口:host=>" + HOST + ",port=>" + PORT);
        try {
            // 初始化套接字,设置访问服务的主机和进程端口号,HOST是访问python进程的主机名称,可以是IP地址或者域名,PORT是python进程绑定的端口号
            socket = new Socket(HOST, PORT);
            // 获取输出流对象
            OutputStream os = socket.getOutputStream();
            PrintStream out = new PrintStream(os);
            // 发送内容
            out.print(str);
            // 告诉服务进程,内容发送完毕,可以开始处理
            out.print("over");
            // 获取服务进程的输入流
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is, "utf-8"));
            String tmp = null;
            StringBuilder sb = new StringBuilder();
            // 读取内容
            while ((tmp = br.readLine()) != null)
                sb.append(tmp).append('\n');
            // 解析结果
            System.out.println("接收数据:" + sb.toString());

            // 解析成数组
            // JSONArray res = JSON.parseArray(sb.toString());

            // 解析成对象
            JSONObject res = JSON.parseObject(sb.toString());
            return res;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            log.info("远程接口调用结束");
        }
        return null;
    }
}

Java端发送数据

package cn.edu.xxx.computer.XXX.socket;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class PythonSocketTests {

    @Test
    public void testremoteCall() throws Exception {
        PythonSocket pythonSocket = new PythonSocket();
        pythonSocket.remoteCall("hello");
    }

}

Java端控制台输出

发送内容(JSONObject):{"content":"hello"}
发送内容(String):{"content":"hello"}
2021-07-30 20:27:40.781  INFO 7340 --- [           main] c.e.u.c.G.socket.PythonSocket            : 调用远程接口:host=>192.168.219.1,port=>12345
接收数据:{"content": "world"}

2021-07-30 20:27:40.836  INFO 7340 --- [           main] c.e.u.c.G.socket.PythonSocket            : 远程接口调用结束

Python端控制台输出

服务器地址:('192.168.219.1', 12345)
连接地址:('192.168.219.1', 64874)
开启线程.....
解码后数据:
{"content":"hello"}over
解析成JSON数据:
{'content': 'hello'}
修改JSON数据并发送:
{"content": "world"}
任务结束.....