Kotlin客户端与Linux Python3 Socket服务器图片收发问题解决
图片Socket收发问题解决
现有代码的核心问题
- Kotlin客户端直接发送图片字节数组,但未告知服务器数据总长度,服务器仅固定接收1024字节,无法获取完整图片数据
- Python服务器仅单次调用
recv,无法接收超过1024字节的图片数据 - Python代码缺少numpy导入,且未处理图片接收后的验证与保存逻辑
修正后的Kotlin客户端代码
确保先发送图片字节数组的长度,再发送图片数据(示例中直接从资源读取Bitmap转换为字节流):
class MainActivity : AppCompatActivity() { lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) Client().start() } class Client : Thread() { override fun run() { try { val socket = Socket("35.216.104.58", 3000) val dos = DataOutputStream(socket.getOutputStream()) // 从资源读取图片并转换为字节数组 val bitmap = BitmapFactory.decodeResource(applicationContext.resources, R.drawable.your_image) val byteArrayOutputStream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream) val imageBytes = byteArrayOutputStream.toByteArray() // 先发送图片字节数组的长度(4字节整数) dos.writeInt(imageBytes.size) // 再发送完整的图片数据 dos.write(imageBytes) dos.flush() dos.close() socket.close() } catch (e: Exception) { e.printStackTrace() } } } }
修正后的Python服务器代码
先接收数据长度,再循环接收所有图片字节,最后解码保存:
import socket import cv2 import numpy as np ip = '' port = 3000 server_socket = socket.socket(socket.AF_INET) server_socket.bind((ip, port)) server_socket.listen(1) print('Waiting Client...') client_socket, addr = server_socket.accept() print('Connect Client!!') # 先接收4字节的长度数据(对应Kotlin的writeInt) length_data = client_socket.recv(4) if not length_data: print("未收到数据长度") client_socket.close() server_socket.close() exit() image_length = int.from_bytes(length_data, byteorder='big') print(f"图片数据长度: {image_length}") # 循环接收所有图片数据,每次最多收4096字节 received_data = b'' while len(received_data) < image_length: chunk = client_socket.recv(min(image_length - len(received_data), 4096)) if not chunk: break received_data += chunk # 验证并处理图片 if len(received_data) == image_length: encoded_img = np.frombuffer(received_data, dtype=np.uint8) image = cv2.imdecode(encoded_img, cv2.IMREAD_COLOR) if image is not None: cv2.imwrite("received_image.jpg", image) print("图片接收并保存成功") cv2.imshow("Received Image", image) cv2.waitKey(0) cv2.destroyAllWindows() else: print("图片解码失败") else: print("图片数据接收不完整") client_socket.close() server_socket.close()
关键注意事项
- 必须先发送数据长度,让服务器明确需要接收的总字节数,避免数据截断
- 服务器需循环接收数据,直到获取到所有长度的字节,不能单次固定接收小容量数据
- 客户端与服务器的图片压缩格式要统一(示例用JPEG)
- 增加异常处理,覆盖连接中断、数据接收不全、解码失败等场景
内容的提问来源于stack exchange,提问作者김현종
相关产品推荐
相关产品推荐

