C/C++ code
#include
<
stdio.h
>
#include
<
iostream
>
#include
<
winsock2.h
>
#include
<
process.h
>
#include
"
SockInit.h
"
using
namespace
std;
#define
MAX_REQUESTLINE_LEN 2048
//
IE请求行长度
void
__cdecl ServerThreadProc(
void
*
param);
int
TCPsend(SOCKET s,
const
char
*
buf,
int
len,
int
flags);
int
TCPrecv(SOCKET s,
const
char
*
buf,
int
len,
int
flags);
/*
*********************************************** 调试环境:Visual C++6.0 SP6+platform SDK 2003 R2 程序名称:HTTP proxy Server(HttpProxySvr.cpp) 功能 :IE通过设置代理方式上网,IE所有请求均 先发到该代理服务器,代理服务器 将请求直接转发给webserver, 后从webserver读取响应后发回IE 存在的问题: IE设置代理后只能显示网页文本内容,图片 显示不了,若网页嵌有歌曲,歌曲也下载不 下来(自然歌曲也播放不了)... Date: 2007/10/12 author: liqisong eamil : [email protected] *************************************************
*/
int
main() { USHORT uPort
=
9999
;
//
通信端口
WORD wVersionRequested; WSADATA wsaData;
int
err; wVersionRequested
=
MAKEWORD(
2
,
2
); err
=
WSAStartup( wVersionRequested,
&
wsaData );
if
( err
!=
0
) {
return
0
; }
if
( LOBYTE( wsaData.wVersion )
!=
2
||
HIBYTE( wsaData.wVersion )
!=
2
) { WSACleanup( );
return
0
; } SOCKET sListen
=
socket(AF_INET,SOCK_STREAM,
0
);
if
(sListen
==
INVALID_SOCKET) { printf(
"
Failed socket(),error code :%d
"
,WSAGetLastError());
return
0
; } sockaddr_in sin; sin.sin_addr.S_un.S_addr
=
INADDR_ANY; sin.sin_family
=
AF_INET; sin.sin_port
=
htons(uPort);
if
(bind(sListen,(sockaddr
*
)
&
sin,
sizeof
(sin))
==
SOCKET_ERROR) { printf(
"
Failed bind(),error code :%d
"
,WSAGetLastError()); closesocket(sListen);
return
0
; }
int
res
=
listen(sListen,
200
); sockaddr_in addrRemote;
int
len
=
sizeof
(addrRemote);
while
(
true
) { SOCKET sNew
=
accept(sListen,(sockaddr
*
)
&
addrRemote,
&
len);
if
(sNew
==
INVALID_SOCKET) { printf(
"
Failed accept(),error code :%d
"
,WSAGetLastError());
return
0
; } printf(
"
收到一个IE连接(IP:%s)\n
"
,inet_ntoa(addrRemote.sin_addr));
//
创建一个线程处理该连接 (每客户单线程模式...)
_beginthread(ServerThreadProc,
0
,(
void
*
)sNew); } closesocket(sListen);
return
0
; }
void
__cdecl ServerThreadProc(
void
*
param) { SOCKET sock
=
(SOCKET)param;
//
与浏览器连接的套接口
char
request[MAX_REQUESTLINE_LEN]; memset(request,
0
,MAX_REQUESTLINE_LEN);
int
res
=
recv(sock,request,MAX_REQUESTLINE_LEN,
0
);
//
接收浏览器(客户端)发来的请求
if
(res
==
0
) { printf(
"
连接断开\n
"
); closesocket(sock);
return
; } shutdown(sock,SD_RECEIVE);
//
打印收到的请求
printf(
"
header length :%d header: %s\n
"
,res,request);
//
分析请求行(分离出WebServer域名)
char
szAddrName[
1024
]
=
{
0
};
//
域名
int
i
=
11
;
while
(request[i]
!=
'
/
'
&&
i
<
res) { szAddrName[i
-
11
]
=
request[i]; i
++
; } szAddrName[i
-
11
]
=
'
\0
'
; printf(
"
WebServer address: %s\n\n
"
,szAddrName);
//
向WebServer提交请求
SOCKADDR_IN saServer; LPHOSTENT lphostent; SOCKET hsocket;
int
nRet; lphostent
=
gethostbyname(szAddrName);
//
通过域名获得目标WebServer的IP
if
(lphostent
==
NULL) { printf(
"
Failed gethostbyname(),error code:%d\n
"
,WSAGetLastError());
return
; } hsocket
=
socket(AF_INET,SOCK_STREAM,
0
);
if
(hsocket
==
INVALID_SOCKET) { printf(
"
Failed socket(),error code:%d\n
"
,WSAGetLastError());
return
; } saServer.sin_family
=
AF_INET; saServer.sin_port
=
htons(
80
); saServer.sin_addr
=
*
((LPIN_ADDR)
*
lphostent
->
h_addr_list); nRet
=
connect(hsocket,(LPSOCKADDR)
&
saServer,
sizeof
(SOCKADDR_IN));
if
(nRet
==
SOCKET_ERROR) { printf(
"
Failed connect(),error code:%d\n
"
,WSAGetLastError()); closesocket(hsocket);
return
; }
//
向webserver转发IE请求
nRet
=
TCPsend(hsocket,request,strlen(request),
0
);
char
dest[
1000
]; nRet
=
1
;
int
senlen
=
0
;
while
(nRet
>
0
) { memset(dest,
0
,
1000
); nRet
=
recv(hsocket,dest,
sizeof
(dest)
-
1
,
0
);
//
从webserver获取数据
if
(nRet
==
0
) { printf(
"
与webserver(%s)的连接关闭\n
"
,szAddrName);
break
; }
else
if
(nRet
==
SOCKET_ERROR ) { printf(
"
Failed recv(),error code:%d\n
"
,WSAGetLastError());
break
; } dest[nRet]
=
'
\0
'
; senlen
=
TCPsend(sock,dest,strlen(dest),
0
);
//
将数据转发给IE浏览器
if
(senlen
==
0
) { sockaddr_in sin;
int
len
=
sizeof
(sin);
if
(getpeername(sock,(sockaddr
*
)
&
sin,
&
len)
==
SOCKET_ERROR) { printf(
"
Failed getpeername(),error code:%d\n
"
,WSAGetLastError());
break
; } printf(
"
与浏览器(%s)的一个连接关闭...\n
"
,inet_ntoa(sin.sin_addr));
break
; }
else
if
(senlen
==
SOCKET_ERROR) { printf(
"
Failed send(),error code:%d\n
"
,WSAGetLastError());
break
; }
//
printf("%s\n",dest);
}
//
end of while(nRet>0)
closesocket(sock); closesocket(hsocket); }
int
TCPsend(SOCKET s,
const
char
*
buf,
int
len,
int
flags) {
int
n
=
0
,sendCount
=
0
;
int
length
=
len;
if
(buf
==
NULL)
return
0
;
while
(length
>
0
) { n
=
send(s,buf
+
sendCount,length,flags);
//
发送数据,
if
(n
==
SOCKET_ERROR)
//
网络出现异常
{ printf(
"
Failed send(),error code:%d\n
"
,WSAGetLastError());
break
; } length
-=
n; sendCount
+=
n; }
return
sendCount;
//
返回已发送的字节数
}
int
TCPrecv(SOCKET s,
char
*
buf,
int
len,
int
flags) {
int
nRev
=
0
,recvCount
=
0
;
int
length
=
len;
if
(buf
==
NULL)
return
0
;
//
循环接收数据
while
(length
>
0
) { nRev
=
recv(s,buf
+
recvCount,length,flags);
if
(nRev
==
SOCKET_ERROR)
//
网络出现异常
{ printf(
"
Failed recv(),error code:%d\n
"
,WSAGetLastError());
break
; } length
-=
nRev; recvCount
+=
nRev; }
return
recvCount;
//
返回接收到的字节数
}
以下一行出错了
senlen = TCPsend(sock,dest,strlen(dest),0); //将数据转发给IE浏览器
因为接受图片不是字符串,用strlen()不会正确,用nRet即可。