35 }else if(readlineCount==2){ 36 int i=n; 37 while(buf[i]!='='){ 38 if((buf[i]>='0'&&buf[i]<='9') 39 ||(buf[i]>='a'&&buf[i]<='z') 40 ||(buf[i]>='A'&&buf[i]<='Z') 41 ||(buf[i]=='.')) 42 i--; 43 else{ 44 buf[i]='*'; 45 i--; 46 } 47 } 48 file=std::string(buf+i+2,buf+n-3); 49 }else if(readlineCount==3){ 50 std::string rw; 51 rw=std::string(buf,buf+strlen(buf)); 52 int pos=rw.find('/'); 53 rw=rw.substr(0,pos); 54 filename=filename+file; 55 if(rw=="Content-Type: text") 56 outStream.open(filename.c_str()); 57 else{ 58 outStream.open(filename.c_str(),std::ios::binary); 59 std::cout<<"ios::binary"< 60 } 61 }else if(readlineCount==4){ 62 memset(buf,0,sizeof(buf)); 63 while(1){ 64 n=s.server_readn(confd,buf,sizeof(buf)); 65 if(n==boundary.size()&&strcmp(buf,boundary.c_str())==0){ 66 goto exit; 67 } 68 nread+=n; 69 if(buf[n-1]==0){ 70 outStream.write(buf,n-1); 71 }else{ 72 outStream.write(buf,n); 73 } 74 } 75 } 76 readlineCount++; 77 } 78 exit: 79 outStream.close(); 80 s.server_close(confd); 81 return nread; 82 } 83 std::string HttpRequest::getMethod() const{ 84 return method; 85 } 86 std::string HttpRequest::getUrl() const{ 87 return url; 88 } 89 std::string HttpRequest::getHost() const{ 90 return host; 91 } 92 }

好了上传文件的代码也已经出来了,现在就是对其稍微的解释一下把。在解释代码之前先看一下我们在点击上传文件按钮的时候,浏览器给服务器发送的内容是什么,比如我有一个test.txt的文本文件(这里采用文件文件是为了好查看内容,其实二进制文件也是一致的)。test.txt文件的内容只有一行就是aaabbb这6个字母。接着打开可以火狐的开发者网络这一功能。并且点击发送文件后,可以在消息头上看到如下信息。

这些内容在之前的章节已经讲过了,这里就不重复了,并且点击参数这一选项可以看到如下信息。

 

在这里第1,2行是请求头的内容,接着一行空行之后是请求体4-9行。看到请求体的内容不是直接是test.txt的内容。显示‘--23469111452’为开头,拜师这个是文本的分隔符。前面固定一段'-',加上一个浏览器自动产生的数据。并且一个文件的解释也是这样,只是数字后面多了2个'-'。在第5,6行是对上传的文件的描述。接着是一行空行。第8行开始就是文件的内容了。知道这个请求体后,很容易的就可以写出代码。上面的的upload中readlineCount变量就是起到定位功能。看服务器已经接收到那一行了,这里s.server_readn这个行数之间没有提交,现在的代码段一直在修改,所以有些与博客有点差别,大体上还是一致的。




相关内容