2015-04-01 17 views
0

我在linux上使用v4l2庫,拍照並想通過c程序將它發送到php服務器。 我想使用套接字來做到這一點。但我不知道如何傳遞圖片來請求。 這是我的示例代碼:從linux(使用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:抱歉我的英語技能。

回答

0

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

HTML 4.01 specification

內容類型「application/X WWW的窗體-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); 

如果您無需等待響應剛剛關閉套接字服務器可能會投訴並返回錯誤。您還應該檢查回覆是否確認有效的請求。