简体   繁体   English

从Linux(使用不带curl的c)将图像发布到php服务器

[英]Post image from linux (using c without curl) to php server

I am using v4l2 library on linux, take a picture and want to send it to a php server via c program. 我在linux上使用v4l2库,拍了张照片,并想通过c程序将其发送到php服务器。 I want to using a socket to do it. 我想用一个插座来做。 But i don't know how to pass the image to request . 但是我不知道如何传递图像来请求。 This is my sample code: 这是我的示例代码:

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));

Can i using this way to post an image to server (include its name) ? 我可以使用这种方式将图像发布到服务器(包括其名称)吗? Any suggest for me ? 有什么建议吗? Thanks PS: sorry about my english skill. 谢谢PS:对我的英语能力感到抱歉。

You are including only file name. 您仅包括文件名。 You have to include the whole image file contents into post data stream. 您必须将整个图像文件内容包括到发布数据流中。 Forms submitting binary data with POST request should use multipart/form-data content type. 带有POST请求提交二进制数据的表单应使用multipart/form-data内容类型。 You can't use application/x-www-form-urlencoded type. 您不能使用application/x-www-form-urlencoded类型。

From HTML 4.01 specification : 根据HTML 4.01规范

The content type "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. 内容类型“ application / x-www-form-urlencoded”对于发送大量二进制数据或包含非ASCII字符的文本效率不高。 The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data. 内容类型“ multipart / form-data”应用于提交包含文件,非ASCII数据和二进制数据的表单。

You could adjust your code like this: 您可以这样调整代码:

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));

After sending data you should read server response, for example: 发送数据后,您应该阅读服务器响应,例如:

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);

If you just close socket without waiting for the response server may complain and return error. 如果仅关闭套接字而不等待响应服务器,则可能会抱怨并返回错误。 You should also check if the response confirms valid request. 您还应该检查响应是否确认有效请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM