【问题标题】:Post image from linux (using c without curl) to php server将图像从 linux(使用不带 curl 的 c)发布到 php 服务器
【发布时间】:2015-04-01 08:53:06
【问题描述】:

我在linux上使用v4l2库,拍照并想通过c程序将其发送到php服务器。 我想使用套接字来做到这一点。但我不知道如何将图像传递给 request 。 这是我的示例代码:

int portno =        80;
struct sockaddr_in serv_addr;
int sockfd, bytes, sent, received, total;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
char message[1024],response[4096];
if (sockfd < 0){
    printf("ERROR opening socket");
}
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
if(inet_pton(AF_INET, CONST_DOMAIN, &serv_addr.sin_addr)<=0){
    printf("\n inet_pton error occured\n");
    return 1;
}
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) {
    printf("ERROR connecting");
}
char content[1024];
char *contentTemp="image_name=%s";
sprintf(content,contentTemp,imageName);
char *headerTemp="POST %supload.php HTTP/1.0\r\nHost: %s\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-length: %d\r\n\r\n%s";
sprintf(message,headerTemp,SERVICE_PATH,SERVICE_HOST,strlen(content),content);
write(sockfd,message,strlen(message));

我可以使用这种方式将图像发布到服务器(包括其名称)吗? 对我有什么建议吗? 谢谢 PS:对不起我的英语水平。

【问题讨论】:

    标签: php c linux sockets


    【解决方案1】:

    您只包括文件名。您必须将整个图像文件内容包含到发布数据流中。使用POST 请求提交二进制数据的表单应使用multipart/form-data 内容类型。不能使用application/x-www-form-urlencoded 类型。

    来自HTML 4.01 specification

    内容类型“application/x-www-form-urlencoded”效率低下 用于发送大量二进制数据或包含 非 ASCII 字符。内容类型“multipart/form-data”应该是 用于提交包含文件、非 ASCII 数据和 二进制数据。

    你可以像这样调整你的代码:

    char *filename="file.jpg"; // this example uses jpeg
    
    // optionally load file from filesystem
    // though I think you have it in a buffer, don't you?
    FILE *file = fopen(filename, "rb");
    char binary[1024]; // adjust buffer size to your needs
    size_t filesize = fread(binary, 1, sizeof(binary), file);
    // check for error here to make sure read succeeded
    fclose(file);
    
    // multipart/form-data POST header
    const char *headerTemp = "POST %supload.php HTTP/1.0\r\n"
                     "Host: %s\r\n"
                     "Content-Type: multipart/form-data; boundary=BoUnDaRy\r\n"
                     "Content-Length: %lu\r\n"
                     "\r\n";
    // first and only part beginning
    const char *bodyTemp =
                     "--BoUnDaRy\r\n"
                     "Content-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n"
                     "Content-Type: image/jpeg\r\n"
                     "Content-Transfer-Encoding: binary\r\n"
                     "\r\n";
    // and ending
    const char body2[] = "\r\n"
                     "--BoUnDaRy--\r\n";
    char body1[1024]; // adjust buffer size to your needs
    // calculate body size, will be included in Content-Length header
    size_t body_size = strlen(body1) + strlen(body2) + filesize;
    snprintf(header, 1024, headerTemp, SERVICE_PATH, SERVICE_HOST, body_size);
    snprintf(body1, 1024, bodyTemp, filename);
    // you should add checking for each write return value
    write(sockfd, header, strlen(header));
    write(sockfd, body1, strlen(body1));
    write(sockfd, binary, filesize);
    write(sockfd, body2, strlen(body2));
    

    发送数据后你应该读取服务器响应,例如:

    while (1) {
        ssize_t result = recv(sockfd, response, sizeof(response), 0);
        if (result == 0) {
            break;
        } else if (result < 0) {
            perror("reading socket failed");
            break;
        }
        printf("%s\n", response);
    }
    close(sockfd);
    

    如果您只是关闭套接字而不等待响应服务器可能会抱怨并返回错误。您还应该检查响应是否确认了有效的请求。

    【讨论】:

      猜你喜欢
      • 2019-01-25
      • 1970-01-01
      • 1970-01-01
      • 2015-09-13
      • 2022-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多