使用Socket实现图片上传服务器功能

一、实现思路

1、客户端(Java实现)

(1) 判断所要上传的图片的大小与类型

(2) 与服务器建立Socket连接

(3) 发送图片的大小与类型信息给服务器

(4) 接收服务器的确认信息,并发送图片给服务器

(5) 接收服务的回传信息

2、服务器(Python实现)

(1) 监听指定端口,接收Socket连接请求

(2) 启用多线程处理连接请求

(3) 接收客户端发送的图片大小与类型信息,并回传确认信息给客户端

(4) 接收图片并保存到本地

(5) 发送接收完毕消息给客户端

二、详细代码

客户端(Java实现)

import net.sf.json.JSONObject;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashSet;
import java.util.Objects;


public class SocketClient {

    //允许上传的图片类型
    private final HashSet<String> IMG_TYPE = new HashSet<String>() {{
        add("png");
        add("jpeg");
        add("jpg");
    }};
    //允许上传的图片大小(10MB)
    private final int MAX_LENGTH = 1024 * 1024 * 10;
    //服务器IP地址
    private final String URL = "192.168.56.1";
    //服务器端口号
    private final int PORT = 9877;
    //图片路径
    private final String ImgPath = "src/4.jpeg";
    private Socket mSocket;
    private OutputStream outputStream;
    private InputStream inputStream;

    public SocketClient() {
        try {
            SendImage();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    //发送图片到服务器
    public void SendImage() throws IOException, InterruptedException {
        File file = new File(ImgPath);
        //图片长度
        long imgLength = file.length();
        //图片类型
        String imgType = Files.probeContentType(file.toPath()).split("/")[1];
        System.out.println("图片大小:" + imgLength + "B;图片类型:" + imgType);
        //对文件大小及类型进行限制判断
        if (imgLength > MAX_LENGTH) {
            System.out.println("图片超出最大限制,请重新选择一张图片!");
            return;
        } else if (!IMG_TYPE.contains(imgType)) {
            System.out.println("文件类型不符合要求,请重新选择一张图片!");
            return;
        }
        //建立Socket连接
        mSocket = new Socket(InetAddress.getByName(URL), PORT);
        System.out.println("与服务器建立连接成功!");

        //获取socket输出流与输入流
        outputStream = mSocket.getOutputStream();
        inputStream = mSocket.getInputStream();

        //发送图片详细信息给服务器
        //使用JSON格式对数据进行封装
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("Length", imgLength);
        jsonObject.put("FileType", imgType);
        //将JSON格式数据转换成字节数组,使用UTF-8编码
        byte[] sendMessage = jsonObject.toString().getBytes(StandardCharsets.UTF_8);
        //发送字节数组
        outputStream.write(sendMessage);

        //接收服务器端发送过来的确认数据
        System.out.println("接收服务器的确认数据中......");
        String confirmData = readMessage();
        System.out.println("服务器确认信息:" + confirmData);
        if (!Objects.equals(confirmData, "OK")) {
            System.out.println("发送给服务器的图片信息错误");
            return;
        }
        System.out.println("接收确认消息完成......");

        //发送图片------------------
        //获取图片的缓冲输入流
        System.out.println("图片上传中......");
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
        int readLen;
        byte[] buf = new byte[1024];
        while ((readLen = bis.read(buf)) != -1) {
            outputStream.write(buf, 0, readLen);
        }
        mSocket.shutdownOutput();
        System.out.println("图片上传完成......");

        //接收来自服务端的回复
        String result = readMessage();
        System.out.println("服务器回传消息:" + result);

        //关闭图片缓冲输入流
        bis.close();
        //关闭socket输入流
        inputStream.close();
        //关闭socket输出流
        outputStream.close();
        //断开socket连接
        mSocket.close();
    }
    
    //读取服务器发送过来的消息
    private String readMessage() {
        try {
            byte[] bytes = new byte[1024];
            int len = inputStream.read(bytes);
            return new String(bytes, 0, len);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        new SocketClient();
    }
}

服务器(Python实现)

import socket
import time
import json
from threading import Thread

# 服务器主机地址和监听的端口号
HOST = socket.gethostname()
PORT = 9877


# 服务端回应消息
def response_message():
    message = 'I have receive your image'
    return message.encode("utf-8")


# 接收图片数据
def recv_img(client_sock):
    data = b''
    print("开始接收客户端数据--------")
    try:
        confirm_data = client_sock.recv(1024)
        print(confirm_data.decode('utf-8'))
        json_data = json.loads(confirm_data)
        img_type = json_data['FileType']
        img_length = json_data['Length']
        client_sock.send('OK'.encode('utf-8'))
        print('发送确认消息完成--------')
    except KeyError as a:
        print("图片信息数据错误:" + str(a))
        client_sock.send('ERROR')
        return

    print("开始接收图片数据---------------")
    while len(data) < img_length:
        try:
            recv_data = client_sock.recv(1024000)
            time.sleep(0.1)
            data += recv_data
        except Exception as e:
            print("Socket接收数据错误:" + str(e))
            break
    if len(data) != 0:
        save_image(data, img_type)
    else:
        print("Client Close!")


# 将传输过来的图片保存到img目录下
def save_image(imageData, imgType):
    _time = time.strftime("%Y%m%d_%H%M%S", time.localtime())
    imageSavePath = "img/" + _time + "." + imgType
    print(imageSavePath)
    file = open(imageSavePath, 'wb+')
    file.write(imageData)
    file.close()


# 处理客户端请求过来的数据
def accept_data(client_sock, client_addr):
    recv_img(client_sock)
    # 生成回复消息
    response = response_message()
    # 发送服务器回应消息
    client_sock.send(response)
    # 关闭与客户端的socket连接
    client_sock.shutdown(1)
    client_sock.close()


# Socket 服务器类
class SocketServer:
    def __init__(self, host=HOST, port=PORT):
        self.sock = None
        self.host = host
        self.port = port
        self.setup_socket()
        self.accept()
        self.shout_down_socket()

    # 建立Socket连接
    def setup_socket(self):
        # 创建 socket 对象
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 绑定端口号
        self.sock.bind((self.host, self.port))
        # 设置最大连接数,超过后排队
        self.sock.listen(600)

    # 使用多线程接受客户端的请求
    def accept(self):
        while True:
            # address ----> 消息发送方ip地址
            # client ----> 服务器与客户端之间的Socket连接
            (client, address) = self.sock.accept()
            # target ----> 线程执行的方法 ;    args ----> target目标调用的参数元组
            th = Thread(target=accept_data, args=(client, address))
            th.start()

    # 关闭Socket连接
    def shout_down_socket(self):
        if self.sock is not None:
            self.sock.shutdown()
            self.sock.close()


if __name__ == "__main__":
    SocketServer()

客户端Java实现需要导入相关的JSON数据格式的依赖包,依赖包可以在我的Github库中下载

https://github.com/Hunter957/ImageUploadServerhttps://github.com/Hunter957/ImageUploadServer

三、实现效果

94ce8a6252f148eba8845c24a06eaa13.png

 客户端与服务器的Socket通信没有太大问题,图片也没有出现数据丢失的情况

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Halcon是一款强大的图像处理软件,可以用于图像的分析、处理和识别等应用。在Halcon中,可以使用Socket协议实现图像的传输使用Halcon进行图像的Socket传输需要以下几个步骤: 1. 创建Socket连接:首先,需要通过Halcon创建一个Socket连接,用于与接收图像的设备进行通信。可以指定连接类型(TCP或UDP)和远程设备的IP地址和端口号。 2. 打开图像:在传输图像之前,需要先将图像加载到Halcon中进行处理。可以使用Halcon提供的图像加载函数,如read_image,将图像从文件中读取到Halcon的内存中。 3. 图像编码:为了将图像传输给接收设备,需要对图像进行编码。Halcon可以使用各种编码方式,如JPEG、PNG、BMP等,将图像编码为二进制数据。 4. 图像传输:通过Socket连接将图像发送给接收设备。可以使用Halcon提供的Socket相关函数,如send_socket,将编码后的图像数据发送给远程设备。 5. 图像解码:接收设备接收到图像数据后,需要进行解码以还原图像。在接收设备中,可以使用相应的解码算法,如解码JPEG图像的libjpeg库,将接收到的二进制数据解码为图像。 6. 图像显示:解码后的图像可以通过合适的方式显示出来,以供操作或观察。在接收设备中,可以使用Halcon提供的图像显示函数,如disp_image,将图像显示在窗口或屏幕上。 通过以上步骤,可以实现Halcon图像的Socket传输。这种方式可以在不同设备之间实现图像的传输和共享,为图像处理提供了更多的可能性和灵活性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值