网络编程之--socket实现python和java通信

4 篇文章 0 订阅
1 篇文章 0 订阅
最近因为项目需求,要求能在python和java之间传输数据,所以了解了一下socket,通过使用socket在两种语言之间传输数据。期间遇见了不少坑,记录一下,算是给后来人一个借鉴(说起来都是泪啊 。。。。。)
1. 先说一下我要干什么,我通过base64编码将图片从前端传到了服务器(java写的网站),然后需要把图片数据传输到python中实现一些功能。其中使用python作为服务端,java作为客户端。
服务端(python)

使用python的socket模块写客户端的时候到时没什么大问题。按照基本步骤来就行了(就当读者已经了解socket的大致运作方式,下面给出代码实现,有注释…)

import socket

# 在构建socket的时候需要用到ip和端口,必须是元组的形式。
# 另外,因为是本机上的两个程序通信,所以设置成localhost,
# 如果要和网络上的其他主机进行通信,则填上相应主机的ip地
# 址,端口的话随便设置一个,不要和已知的一些服务冲突就行
adress = ('localhost', 9999)   
# 创建socket对象,同时设置通信模式,AF_INET代表IPv4,SOCK_STREAM代表流式socket,使用的是tcp协议
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定到我们刚刚设置的ip和端口元组,代表我们的服务运行在本机的9999端口上
server.bind(address)
# 开始监听,5位最大挂起的连接数
server.listen(5)
# 无限循环,实现反复接收请求
while True:
	# accept()方法被动接受客户端连接,阻塞,等待连接. client是客户端的socket对象,可以实现消息的接收和发送,addr表示客户端的地址
	client, addr = server.accept()
	data = client.recv(13)  # 代表从发过来的数据中读取13byte的数据
	data1 = client.recv(4)   # 再接收4byte数据
	client.sendall(b'1')    # 发送消息给客户端,发送的消息必须是byte类型
	client.close()        # 关闭连接
server.close()

呼,终于写完了,感觉注释应该很详细了吧。
我必须要再说一点很重要的东西:服务端每次接受的数据是有限制的,也就是说文件大一点的话你要分好多次接收,比如我要传输图片的话只接收一次是根本接收不全的,每次收到的数据都少很多。一定要注意!一定要注意!一定要注意!
附上我的解决代码(献丑了 ? )

img_base64 = b''
max_size = 1024      # 设置每次接收1024byte,当然也可以更大,只要不超过缓冲区大小就行
sum = img_length     # img_length是我的图片数据的长度
      
while sum >= max_size:          # 每次接收1024,直到剩下的数据小于1024
   img_base64 = img_base64 + conn.recv(max_size)
   sum -= max_size

if sum != 0:                      # 如果还剩下数据的话就接收完
   mg_base64 = img_base64 + conn.recv(sum)   

python服务端的代码就到此为止了。。

但是 ! ! !, 我还有问题要说,我原来是想传过来base64编码的图片数据,然后用python解码然后转换成图片,但是没搞成功,不是出现Incorrect padding异常就是解码后的数据不能正常使用,着实是没搞懂(黑人问号脸???)是python的base64太垃圾了?还是我太垃圾了?(沮丧。。)
然后把解码base64图片的工作放在了java中就行了。。。

客户端(java)

用java做客户端还是很好写的,网上的资源也是很全的,直接上代码了:
我把通信过程都放在了一个函数里面,传入的参数是两个byte[]类型的数据,这是我的项目要求,对于读者来说也可以传入一个或多个都行

// 传递信息
	public String sendMessage(byte[] header, byte[] data) {
		String ip = "localhost";        // 设置发送地址和端口号
		int port = 9999;
		Socket socket = null;
		try {
			// 连接服务器
			socket = new Socket(ip, port);
			// 获取输入流
			InputStream in = socket.getInputStream();   //读取数据
			// 获取输出流
			OutputStream out = socket.getOutputStream(); // 发送数据
			// 包装输入流,输出流,包装一下可以直接传输字符串,不包装的话直接使用InputStream和OutputStream只能直接传输byte[]类型数据
			BufferedReader inRead = new BufferedReader(new InputStreamReader(in));
//			PrintWriter outWriter = new PrintWriter(out);
			
			// 发送数据
			out.write(header);
			out.write(data);
		
			// 接受应答
			String result = inRead.readLine();  // 使用了包装后的输入流方便读取消息
			return result;
		} catch(UnknownHostException e) {
			e.printStackTrace();
		} catch(IOException e) {
			e.printStackTrace();
		}
		return "defeat";
	}
  • 11
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值