1.建立到服务器的TCP连接
- HTTP基本TCP,所以我们需要与服务器建立连接,然后才能发送数据
/*
*打开Socket,返回socketId,-1表示失败
*/
int socket_open(int IP,int Port,int type){
SOCKET socketId;
struct sockaddr_in serv_addr;
int status;
socketId=socket(AF_INET,SOCK_STREAM,0);
if((int)socketId<0)
{
printf("[ERROR]Create a socket failed!/n");
return -1;
}
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr = ntohl(IP);
serv_addr.sin_port = htons((USHORT)Port);
status=connect(socketId,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
if(status!=0)
{
printf("[ERROR]Connecting failed!/n");
closesocket(socketId);
return -1;
}
return socketId;
}
/// 开始建立链接,0xC0A80001是192.168.0.1的十六进制写法
int socketId=socket_open(0xC0A80001,808,0);
2.向服务器发送GET或者POST报文
- 根据HTTP协议添加协议头,如下使用GET来获取指定URL的指定文档
static const char* protocolHead="GET http://www.xxx.com/index.html HTTP/1.1/n"
"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*/n"
"Accept-Language: zh-cn/n"
"User-Agent:iPanelBrowser/2.0/n"
"Host: www.xxx.com:80/n"
"Connection: close/n/n"
- 发送数据
send(socketId, protocolHead,strlen(protocolHead),0);
3.接受从服务器返回的报文
- 采用select循环查询的方式来判断有无数据到来
- 数据包会保存至缓冲区
struct timeval tm = {0,7};
fd_set fds_r;
int status;
char recvBuf[4096]={‘/0’};
FD_ZERO(&fds_r);
FD_SET(socketId,&fds_r);
status=select(socketId+ 1, &fds_r, 0, 0, &tm); //socketId在这里是最大的fd
if(status > 0 && FD_ISSET(socketId, &fds_r))
{
printf("Socket is readable...fd=[%d]/n",socketId);
recv(socketId,recvBuf,4096,0);
}
- 判断数据接收完成
- 对返回数据的状态进行判断
- 仅当状态为“ HTTP 200 OK ”时才表明正确返回,这时才对数据进行解析并保存
- 如果状态为HTTP 404 NOT FOUND或者其它状态则表明没有找到资源或者出现其它问题
- 数据正确返回时
- 对HTTP数据包进行解析得到Content-Length
- 在包含Content-Length的当前数据包或者随后的数据包中查找第一个空行,这就是内容(Content)的开始位置,配合前面解析得到的Content-Length就可以确定数据是否接收完成
- 对返回数据的状态进行判断
网友评论