简体   繁体   中英

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. 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.

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. You can't use application/x-www-form-urlencoded type.

From HTML 4.01 specification :

The content type "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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