#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/time.h>
#include <sys/select.h>
#include <fcntl.h>
#include <errno.h>
#define SERVER_ADDR "192.168.1.123"
#define SERVER_PORT 10086
char upload_head[] =
"POST /Logupload/upload?userid=%s HTTP/1.1\r\n"
"Host: %s:%d\r\n"
"Connection: keep-alive\r\n"
"Content-Type: multipart/form-data; boundary=%s\r\n"
"Content-Length: %d\r\n\r\n"
"--%s\r\n"
"Content-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n"
"Content-Type: application/octet-stream;chartset=UTF-8\r\n\r\n";
char upload_request[] =
"--%s\r\n"
"Content-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n"
"Content-Type: application/octet-stream;chartset=UTF-8\r\n\r\n";
int Connect_Server(char *severip,int port)
{
int sock = -1;
struct sockaddr_in addr;
if(severip == NULL || port <= 0)
return -1;
memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
inet_pton(AF_INET,severip,&addr.sin_addr.s_addr);
sock = socket(AF_INET,SOCK_STREAM,0);
if(-1 == sock)
return -1;
if(connect(sock,(struct sockaddr*)&addr,sizeof(addr)) < 0)
{
close(sock);
return -1;
}
return sock;
}
int main(int argc,char *argv[])
{
char filename[256] = {0};
int sock = -1;
char send_date[4096] = {0};
char send_end[128] = {0};
char send_request[2048] = {0};
FILE *fp = NULL;
char *userid = "00000000199";
char boundary[64] = {0};
int ret = -1,already = -1,ContentLength = -1;
long long int timestamp;
struct timeval tv;
if(argc < 2)
return -1;
strncpy(filename,argv[1],256);
if(access(filename,F_OK) != 0)
{
printf("file %s not exsit!\n",filename);
return -1;
}
//连接服务器
sock = Connect_Server(SERVER_ADDR,SERVER_PORT);
if(sock < 0 )
{
printf("connect server error!\n");
return -1;
}
//打开要上传的文件,获取文件的大小,用于计算Content-Length的大小
fp = fopen(filename,"rb");
if(fp == NULL)
{
printf("open file %s error!\n",filename);
close(sock);
return -1;
}
fseek(fp,0,SEEK_END);
ContentLength = ftell(fp);
rewind(fp);
//获取毫秒级的时间戳用于boundary的值
gettimeofday(&tv,NULL);
timestamp = (long long int)tv.tv_sec * 1000 + tv.tv_usec;
snprintf(boundary,64,"---------------------------%lld",timestamp);
// Content-Length的大小还包括了对上传文件的描述,开始boundary和结束boundary
ContentLength += snprintf(send_request,2048,upload_request,boundary,filename);
ContentLength +=snprintf(send_end,2048,"\r\n--%s--\r\n",boundary);
//发送的http头和上传文件的描述
ret = snprintf(send_date,4096,upload_head,userid,SERVER_ADDR,SERVER_PORT,boundary,ContentLength,boundary,filename);
if(send(sock,send_date,ret,0) != ret)
{
printf("send head error!\n");
close(sock);
return -1;
}
//循环读取文件,并往服务器上面发送,直到文件结束为止
clearerr(fp);
while(1)
{
memset(send_date,0,sizeof(send_date));
ret = fread(send_date,1,4096,fp);
if(ret != 4096)
{
if(!ferror(fp))
{
if(send(sock,send_date,ret,0) != ret)
{
printf("send the end date error!\n");
close(sock);
fclose(fp);
return -1;
}
fclose(fp);
break;
}
else
{
printf("read file error!\n");
close(sock);
fclose(fp);
return -1;
}
}
if(send(sock,send_date,4096,0) != 4096)
{
printf("send date error\n");
close(sock);
fclose(fp);
return -1;
}
}
//发送最后的boundary结束文件上传。
SEND_END:
memset(send_date,0,sizeof(send_date));
ret = snprintf(send_date,4096,"\r\n--%s--\r\n",boundary);
if(send(sock,send_date,ret,0) != ret)
{
close(sock);
return -1;
}
printf("send to server end date:%s\n",send_date);
//接收返回值,用于判断是否上传成功
memset(send_date,0,sizeof(send_date));
if(recv(sock,send_date,4096,0) < 0)
printf("recv error!\n");
printf("recv:%s\n",send_date);
close(sock);
return 0;
}
评论5