簡體   English   中英

從Linux(使用不帶curl的c)將圖像發布到php服務器

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

我在linux上使用v4l2庫,拍了張照片,並想通過c程序將其發送到php服務器。 我想用一個插座來做。 但是我不知道如何傳遞圖像來請求。 這是我的示例代碼:

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:對我的英語能力感到抱歉。

您僅包括文件名。 您必須將整個圖像文件內容包括到發布數據流中。 帶有POST請求提交二進制數據的表單應使用multipart/form-data內容類型。 您不能使用application/x-www-form-urlencoded類型。

根據HTML 4.01規范

內容類型“ 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);

如果僅關閉套接字而不等待響應服務器,則可能會抱怨並返回錯誤。 您還應該檢查響應是否確認有效請求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM