首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

小弟我用http协议上传 图片 但是 收到的 响应 有有关问题 求大神帮助

2013-09-05 
我用http协议上传 图片 但是 收到的 响应 有问题 求大神帮助调用方法stringstrRecvintnRetUpload 0CSD

我用http协议上传 图片 但是 收到的 响应 有问题 求大神帮助
调用方法

stringstrRecv;
intnRetUpload = 0;
CSDKUploadPic MySend;
//strRecv.substr(
//设置上传服务器的地址  
MySend.SetServerInfo("192.168.1.110","/Default.aspx");
//如果要提交其他的数据,请使用下面的格式,第一个参数为表单名,第二个为表单值
//MySend.MakePostData("homepage","www.lilu.name");
nRetUpload = MySend.UploadPic("2.jpg","img",strRecv);

h文件
#include <string>
#include <Windows.h>

using namespace std;

//提交图片函数,返回值说明
//目前仅支持ASCII编码,不支持UTF8,和unicode。

//定义错误信息
#define UPLOAD_SUCCESS200
#define UPLOAD_WSASTARTUP_ERROR 101
#define UPLOAD_SOCKET_ERROR102
#define UPLOAD_CONNECT_ERROR103
#define UPLOAD_SEND_ERROR104
#define UPLOAD_FILEOPEN_ERROR105
#define UPLOAD_RECV_ERROR106

class CSDKUploadPic
{
public:
DWORD GetHostAddr(const char* lpHost);
void SetServerInfo(char *pHost,char *pRelativeUrl,WORD nPort = 80);
CSDKUploadPic();
~CSDKUploadPic();
//99:图片不存在
//200:正常成功
//101:服务器无法连接
//102:提交页面无法打开
//103:数据发送失败
//404:访问链接未找到
//405:服务器无法支持该请求方式
//500:异常错误
int UploadPic(char *pPicPath,char *pPostName,string &strRecv);
int MakePostData(char *pPostName,char *pPostValue);
protected:
private:
stringm_strPostData;//要发送的数据内容
charm_szPostEndData[200];//协议尾部数据
intm_nContentLen;//数据包字节数
WORDm_nPort;//端口
charm_szRelativeURL[200];//相对URL地址,如:/test/upload.asp
charm_szHost[100];//主机。如:www.lilu.name,或者192.168.0.1
charm_szBoundary[50];//协议内容分隔符,这个不用管。

char*m_pDataBuff;//数据缓存指针,图片,接收数据
const intm_nBuffSize;//缓存的大小
int MakeHeaderData(char *szBuff);
int MakePostPicData(char *pPostName,char *pPicPath);
int MakeEndData();
bool ValidHostChar(char ch);//地址是否合法
};

cpp文件
#include <winsock.h>

#include "SDKUploadPic.h"

#pragma comment(lib,"ws2_32")

CSDKUploadPic::CSDKUploadPic():m_nContentLen(0),m_nBuffSize(65536)
{
strcpy(m_szBoundary,"-----------2893749wrjhewf");
m_pDataBuff = NULL;

}

CSDKUploadPic::~CSDKUploadPic()
{
if (m_pDataBuff)
{
delete []m_pDataBuff;
m_pDataBuff = NULL;
}
}

int CSDKUploadPic::UploadPic(char *pPicPath,char *pPostName,
  string &strRecv)
{
intnRetCode = UPLOAD_SUCCESS;
WSADATAwsadata = {0};
SOCKETsockServer = 0;


SOCKADDR_INaddrServer = {0};//服务器地址
intnRetSend = 0;//发生数据返回值
intnRetRecv = 0;//接收数据返回值


FILE*pFile = NULL;//图片句柄
intnPicSize = 0;//图片大小
intnChunkCount = 0;//图片被分成几块传送
intnLeftLen = 0;//还剩下的字节数
inti = 0;//循环索引
//intnRetLen = 0;//每次发送的字节数
intnIndex = 0;//发送字节的位置索引

if ( 0 != WSAStartup(MAKEWORD(2,2),&wsadata))
{
nRetCode = UPLOAD_WSASTARTUP_ERROR;
goto EXIT0;
}

sockServer = socket(AF_INET,SOCK_STREAM,0);
if (sockServer == INVALID_SOCKET)
{
nRetCode = UPLOAD_SOCKET_ERROR;
goto EXIT0;
}
//服务器信息
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(m_nPort);
addrServer.sin_addr.S_un.S_addr = GetHostAddr(m_szHost);

//连接
if (SOCKET_ERROR == connect(sockServer,(const sockaddr*)&addrServer,sizeof(addrServer)))
{
nRetCode = UPLOAD_CONNECT_ERROR;
goto EXIT0;
}
//开辟缓存
if (m_pDataBuff == NULL)
{
m_pDataBuff = new char[m_nBuffSize];
memset(m_pDataBuff,0,m_nBuffSize);
}
else
{
memset(m_pDataBuff,0,m_nBuffSize);
}

//////////////////////////////////////////////////////////////////////////
//首先发送数据头与图片之前的数据
MakeEndData();
nPicSize = MakePostPicData(pPostName,pPicPath);//生成图片前缀数据,同时加上图片大小。
MakeHeaderData(m_pDataBuff);

m_strPostData = m_pDataBuff + m_strPostData;

nRetSend = send(sockServer,m_strPostData.c_str(),m_strPostData.size(),0);
if (nRetSend <= 0)
{
nRetCode = UPLOAD_SEND_ERROR;
goto EXIT0;
}

//发送图片数据
pFile = fopen(pPicPath,"rb");
if (pFile == NULL )
{
//wprintf(L"打开文件错误!\n");
return UPLOAD_FILEOPEN_ERROR;
}

fseek(pFile,0,SEEK_SET);
//计算块数
nChunkCount = nPicSize / m_nBuffSize + 1;

for (i = 1; i <= nChunkCount; i++)
{
//最后一块
if (i == nChunkCount)
{
nLeftLen = nPicSize - m_nBuffSize * (i-1);
}
else
{
nLeftLen = m_nBuffSize;
}

//定位文件并读取到缓存中。
fread(m_pDataBuff,nLeftLen,1,pFile);

//循环发送直到发送完毕。
nIndex = 0;
while(nLeftLen > 0)
{
nRetSend = send(sockServer,&m_pDataBuff[nIndex],nLeftLen,0);


if (nRetSend == SOCKET_ERROR)
{
break;
}

nLeftLen -= nRetSend;
nIndex += nRetSend;


}
printf("正在发送第%d块数据!\n",i);
}

//关闭文件,释放资源
fclose(pFile);
printf("图片发送完毕!\n");

pFile = NULL;



//发送尾部构造数据
nRetSend = send(sockServer,m_szPostEndData,strlen(m_szPostEndData),0);
if (nRetSend <= 0)
{
nRetCode = UPLOAD_SEND_ERROR;
goto EXIT0;
}


//////////////////////////////////////////////////////////////////////////
//接收数据
//nRetRecv = recv(sockServer,m_pDataBuff,m_nBuffSize,0);
//if (nRetRecv == SOCKET_ERROR)
//{
//nRetCode = UPLOAD_RECV_ERROR;
//goto EXIT0;
//}
//while(nRetRecv > 0)
//{
//strRecv += m_pDataBuff;
////如果缓存接收满了,表示后面还有数据。——这样判断是不准确的,先这样暂时处理。
//nRetRecv = recv(sockServer,m_pDataBuff,m_nBuffSize,0);
//if (nRetRecv == m_nBuffSize)
//{
//nRetRecv = recv(sockServer,m_pDataBuff,m_nBuffSize,0);
//}
//else
//{
//break;
//}
//}
while(true)
{
nRetRecv = recv(sockServer,m_pDataBuff,m_nBuffSize,0);

if(nRetRecv == 0)
{
break;
}
else if(nRetRecv == SOCKET_ERROR)
{
nRetCode = UPLOAD_RECV_ERROR;
goto EXIT0;
}
else
{
strRecv += m_pDataBuff;
}
}

EXIT0:
if (m_pDataBuff)
{
delete []m_pDataBuff;
m_pDataBuff = NULL;
}
if (sockServer != INVALID_SOCKET)
{
closesocket(sockServer);
WSACleanup();
}
return nRetCode;
}

int CSDKUploadPic::MakeHeaderData(char *szBuff)
{
return sprintf(szBuff,"POST %s HTTP/1.1\r\n"
"Accept: text/html,*/*\r\n"
"Accept-Encoding: gzip, deflate\r\n"
"Accept-Language: zh-cn\r\n"
"Content-Type: multipart/form-data; boundary=%s\r\n"
"Cache-Control: no-cache\r\n"
"Connection:Close\r\n"
"Cache-Control: no-cache\r\n"
"Content-length:%d\r\n"
"Host: %s:%d\r\n\r\n",
m_szRelativeURL,m_szBoundary,m_nContentLen,m_szHost,m_nPort
);

}

int CSDKUploadPic::MakePostData(char *pPostName,char *pPostValue)
{
charszBuff[1024] = {0};
int nRet = sprintf(szBuff,"--%s\r\nContent-Disposition: form-data; name="%s"\r\n\r\n%s\r\n",
m_szBoundary,pPostName,pPostValue);



m_nContentLen += nRet;
m_strPostData += szBuff;

return nRet;

}

int CSDKUploadPic::MakePostPicData(char *pPostName,char *pPicPath)
{
charszBuff[1024] = {0};
FILE*pFile = NULL;
int nRet = sprintf(szBuff,"--%s\r\nContent-Disposition: form-data; name="%s";filename="%s"\r\nContent-Type: image/pjpeg\r\n\r\n",
m_szBoundary,pPostName,pPicPath);

m_nContentLen += nRet;
m_strPostData += szBuff;

//获取文件大小
pFile = fopen(pPicPath,"rb");
if (pFile == NULL )
{
//wprintf(L"打开文件错误!\n");
return -1;
}

fseek(pFile,0,SEEK_END);
nRet = ftell(pFile);
rewind(pFile);
fclose(pFile);

m_nContentLen += nRet;

return nRet;
}

int CSDKUploadPic::MakeEndData()
{
int nRet = sprintf(m_szPostEndData,"\r\n--%s\r\nContent-Disposition: form-data; name="Submit"\r\n\r\nsubmit\r\n--%s--",
m_szBoundary,m_szBoundary);
m_nContentLen += nRet;

return nRet;

}

//设置服务器信息
void CSDKUploadPic::SetServerInfo(char *pHost, char *pRelativeUrl, WORD nPort)
{
strcpy(m_szHost,pHost);
strcpy(m_szRelativeURL,pRelativeUrl);
m_nPort = nPort;
}

DWORD CSDKUploadPic::GetHostAddr(const char* lpHost)
{
hostent *phost = NULL;
char*p = NULL;
intiAddrLen = 0;
inti = 0;
//判断,如果是IP地址
iAddrLen = strlen(lpHost);
for (i = 0; i < iAddrLen; i++)
{
//如果即不是数字,也不是点
if ((!isdigit(lpHost[i])) && (lpHost[i] != '.'))
{
break ;
}
//如果检测完毕
if (i == iAddrLen - 1)
{
return inet_addr(lpHost);
}
}
//如果不是IP地址,是网址,检测地址是否合法
for (i = 0; i < iAddrLen; i++)
{
if (!ValidHostChar(lpHost[i]))
{
return 0 ;
}
}
phost = gethostbyname(lpHost);
if (phost == NULL)
{
return 0;
}

//获取地址列表指针
p = *(phost->h_addr_list);

//可以使用下面的代码将IP地址打印出来
//printf("address:%d.%d.%d.%d\n",p[0][0] & 0x00ff,p[0][1] & 0x00ff,p[0][2] & 0x00ff,p[0][3] & 0x00ff);
//printf("address:%02x.%02x.%02x.%02x\n",p[0][0] & 0x00ff,p[0][1] & 0x00ff,p[0][2] & 0x00ff,p[0][3] & 0x00ff);



return *((unsigned long*)p);

}

bool CSDKUploadPic::ValidHostChar(char ch)
{
return (isalpha(ch) || isdigit(ch) || ch == '-' || ch == '.' || ch == ':'|| ch == '/');
}


发送成功后 服务器返回了这个图片的名字但是收到的响应却不对
小弟我用http协议上传 图片 但是 收到的 响应 有有关问题 求大神帮助
小白求帮助
PS:这上传方法是我在网上下的小弟我用http协议上传 图片 但是 收到的 响应 有有关问题 求大神帮助
哪里不对了?

不是回复了 200 么?
[解决办法]


//这是我之前写的,先收头,这样接收的!然后解析头中信息
//根据头中len再去接收消息体
int RecHttpHead(int socketFd, char *pBuffer, unsigned int Time)
{
    char RecBuf[2] = {'\0'};
    int ret = 0;
    char s8Flag  = 0;
    int RecvLen = 0;
    while(1)
    {   
        //      ret = ReadData(socketFd, RecBuf, 1, Time);

        if((ret = recv(socketFd, RecBuf, 1, 0)) <= 0)
        {   


            printf( "[%s]-[%d]: revc error:%s\n", __func__, __LINE__, strerror(errno));
            printf( "[%s]-[%d]: revc error:%d\n", __func__, __LINE__, ret);
            return -1; 
        }   

        if (ret < 0 ) 
        {   
            printf("[%s]-[%d] :Read head failed\n", __FILE__, __LINE__ );
            return -1; 
        }   
        switch(*RecBuf)
        {   
            case '\r':        
                s8Flag++;
                break;          
            case '\n':           
                s8Flag++;        
                break; 
            default:                                                                    
                s8Flag = 0;   
                break;                                                                  


        }   
        strcat(pBuffer, RecBuf);
        RecvLen += ret;
        if( s8Flag >= 4)
            break;
    }   
                                                                                        
    return RecvLen;
}


[解决办法]
引用:
Quote: 引用:



//这是我之前写的,先收头,这样接收的!然后解析头中信息
//根据头中len再去接收消息体
int RecHttpHead(int socketFd, char *pBuffer, unsigned int Time)
{
    char RecBuf[2] = {'\0'};
    int ret = 0;
    char s8Flag  = 0;
    int RecvLen = 0;
    while(1)
    {   
        //      ret = ReadData(socketFd, RecBuf, 1, Time);

        if((ret = recv(socketFd, RecBuf, 1, 0)) <= 0)
        {   
            printf( "[%s]-[%d]: revc error:%s\n", __func__, __LINE__, strerror(errno));
            printf( "[%s]-[%d]: revc error:%d\n", __func__, __LINE__, ret);
            return -1; 
        }   

        if (ret < 0 ) 
        {   
            printf("[%s]-[%d] :Read head failed\n", __FILE__, __LINE__ );


            return -1; 
        }   
        switch(*RecBuf)
        {   
            case '\r':        
                s8Flag++;
                break;          
            case '\n':           
                s8Flag++;        
                break; 
            default:                                                                    
                s8Flag = 0;   
                break;                                                                  
        }   
        strcat(pBuffer, RecBuf);
        RecvLen += ret;
        if( s8Flag >= 4)
            break;
    }   
                                                                                        


    return RecvLen;
}


我按照你的方法接收 的头信息
小弟我用http协议上传 图片 但是 收到的 响应 有有关问题 求大神帮助
我该怎么接收剩下的内容呢?


在根据Content-Length去接收消息体的信息阿!
至于解析的话,得看看对象的协议是怎么样的,然后根据协议来解析消息体就好!
[解决办法]
返回告诉你了,gzip压缩的,先解压
[解决办法]
或者服务器返回时别压缩
[解决办法]
引用:
返回告诉你了,gzip压缩的,先解压


++
[解决办法]
加载zlib库,然后
int deflateUncompress(const char *src, uint32 length, string &buffer)
{
    buffer.clear();
    z_stream strm;

    strm.zalloc   = Z_NULL;
    strm.zfree    = Z_NULL;
    strm.opaque   = Z_NULL;
    strm.avail_in = 0;
    strm.next_in  = Z_NULL;

    int ret = inflateInit2(&strm, 47);//-MAX_WBITS);

    if (ret != Z_OK)
        return ret;

    strm.avail_in = length;
    strm.next_in  = (unsigned char*)src;

    static size_t CHUNK = 1024;
    char *out  = new char[CHUNK];

    do 
    {
        strm.avail_out = CHUNK;
        strm.next_out  = (Bytef*)out;
        ret = inflate(&strm, Z_NO_FLUSH);

        if (ret == Z_STREAM_ERROR)
        {
            delete[] out;
            //throw p2p_cmd_exception_protocol_err( "deflateUncompress Z_STREAM_ERROR!" );
            return ret;
        }

        switch (ret) 


        {
        case Z_NEED_DICT:
            ret = Z_DATA_ERROR; 
        case Z_DATA_ERROR:
        case Z_MEM_ERROR:
            inflateEnd(&strm);
            delete[] out;
            return ret;
        }
        buffer.append(out, CHUNK - strm.avail_out);

    } while (strm.avail_out == 0);

    inflateEnd(&strm);
    delete[] out;

    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; 
}


[解决办法]

我现在让服务器不压缩返回了 但是 怎么 除了"0123456789" 后面还有大堆乱码...小弟我用http协议上传 图片 但是 收到的 响应 有有关问题 求大神帮助

content length是你填的还是谁控制的,这个字段要和你的返回匹配
[解决办法]
贴出你的响应。
1.你的contentlength填错的,导致多发了垃圾。
2.content length对了,但是你没发字符串结束符\0,这边你显示的时候也没注意,打印就是没结尾,屁股是乱码
[解决办法]
content-length 31就不对,还是服务器问题
[解决办法]
引用:
Quote: 引用:

content-length 31就不对,还是服务器问题

额...我服务器就这两句话..

不懂asp,查查有什么注意事项吧,把那31搞到11就对了

热点排行