http 代理

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即可。

你可能感兴趣的:(http)