#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 : liqisong611@yahoo.com.cn **************************************************/ 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即可。