如何利用socket进行HTTP访问
来源:互联网 发布:视频网络直播所需设备 编辑:程序博客网 时间:2024/06/05 11:28
如何利用socket进行HTTP访问
平常我们要访问某个URL一般都是通过浏览器进行:提交一个URL请求后,浏览器将请求发向目标服务器或者代理服务器,目标服务器或者代理服务器返回我们所需要的数据,浏览器接收到这些数据后保存成文件并进行显示。
下面我们看看如何自己利用winsock2.h中的接口来实现这个功能?为了简化问题,作以下假设:
通过代理服务器进行HTTP访问,这样就省去了对URL进行DNS解析的步骤,假设代理服务器的地址为:192.168.0.1:808。
这个功能由以下几个部分组成:
1. 如何建立连接?
2. 如何发送请求?
3. 如何接收数据?
4. 如何判断数据接收完成?
下面我们依次来看下这些问题如何解决
一、如何建立与服务器之间的连接
HTTP基本TCP,所以我们需要与服务器建立连接,然后才能发送数据。
建立连接参考如下函数socket_open:
01
/*
02
*打开Socket,返回socketId,-1表示失败
03
*/
04
int
socket_open(
int
IP,
int
Port,
int
type){
05
SOCKET socketId;
06
struct
sockaddr_in serv_addr;
07
int
status;
08
09
socketId=socket(AF_INET,SOCK_STREAM,0);
10
11
if
((
int
)socketId<0)
12
{
13
printf
(
"[ERROR]Create a socket failed!/n"
);
14
return
-1;
15
}
16
17
memset
(&serv_addr,0,
sizeof
(serv_addr));
18
serv_addr.sin_family=AF_INET;
19
serv_addr.sin_addr.s_addr = ntohl(IP);
20
serv_addr.sin_port = htons((
USHORT
)Port);
21
status=connect(socketId,(
struct
sockaddr*)&serv_addr,
sizeof
(serv_addr));
22
if
(status!=0)
23
{
24
printf
(
"[ERROR]Connecting failed!/n"
);
25
closesocket(socketId);
26
return
-1;
27
}
28
return
socketId;
29
}
调用方式如下:
1
int
socketId=socket_open(0xC0A80001,808,0);
//0xC0A80001是192.168.0.1的十六进制写法。
二、如何发送请求
发送数据要根据HTTP协议的要求附加协议头:
1
static
const
char
* protocolHead=
"GET http://www.xxx.com/index.htmlHTTP/1.1/n"
2
"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"
3
"Accept-Language: zh-cn/n"
4
"User-Agent:iPanelBrowser/2.0/n"
5
"Host: www.xxx.com:80/n"
6
"Connection: close/n/n"
这里使用GET来获取指定URL的指定文档。
建立连接后使用send将这些数据发送出去:
send(socketId, protocolHead,strlen(protocolHead),0);
发送完成HTTP请求后就等待接收数据。
三、如何接收数据
这里采用select循环查询的方式来判断有无数据到来:
01
struct
timeval
tm
= {0,7};
02
fd_set fds_r;
03
int
status;
04
char
recvBuf[4096]={‘/0’};
05
FD_ZERO(&fds_r);
06
FD_SET(socketId,&fds_r);
07
08
status=select(socketId+ 1, &fds_r, 0, 0, &
tm
);
//socketId在这里是最大的fd
09
10
if
(status > 0 && FD_ISSET(socketId, &fds_r))
11
{
12
printf
(
"Socket is readable...fd=[%d]/n"
,socketId);
13
recv(socketId,recvBuf,4096,0);
14
}
这样数据包就保存到缓冲区中了。
四、如何判断数据接收完成
首先对返回数据的状态进行判断,仅当状态为“ HTTP 200 OK ”时才表明正确返回,这时才对数据进行解析并保存,如果状态为HTTP 404 NOT FOUND或者其它状态则表明没有找到资源或者出现其它问题,可参考HTTP 1.1状态代码及其含义。
当数据正确返回时,为了将实际数据从协议中分离出来进行保存,需要对HTTP数据包进行解析得到Content-Length,然后在包含Content-Length的当前数据包或者随后的数据包中查找第一个空行,这就是内容(Content)的开始位置,再配合前面解析得到的Content-Length,就能够知道什么时候数据接收完成了。换行符为“/r/n”,也兼容“/n”或者“/r”,设换行符为^P,则空行如果位于内容中间或结尾则可查找“^P^P”,若位于开头,则查找^P。
基本就是上面这些,这四个问题解决了,那么整个问题也就解决了!
- 如何利用socket进行HTTP访问
- 如何利用socket进行HTTP访问
- 如何利用socket进行HTTP访问
- 如何利用socket进行HTTP访问
- 如何利用socket进行HTTP访问
- 如何利用socket进行HTTP访问
- 如何利用socket进行HTTP访问
- 如何利用socket进行HTTP访问
- 如何利用socket进行HTTP访问
- 如何利用socket进行HTTP访问
- 如何利用socket进行HTTP访问
- JAVA中如何利用socket进行网络编程
- 如何进行 Socket 编程
- 如何进行 Socket 编程
- 如何进行 Socket 编程
- 如何进行 Socket 编程
- 如何进行 Socket 编程
- 利用Socket进行大文件传输
- JDBC查询表返回List通用方法
- java判断字符串是否为数字
- NetBeans 使用phpunit单元测试
- jsp调用存储过程
- NVDKC6416平台H.264算法优化
- 如何利用socket进行HTTP访问
- jdbc连接数据库大全
- 转 Ubuntn命令
- JSP中文链接/tomcat中文路径
- struts文件上传并重命名
- H.264算法的优化策略
- jsp乱码解决大全
- Ubuntu下reload apache报错解决
- 论文阅读报告:PortLand:A Scalable Fault-Tolerant Layer 2 Data Center Network Fabric