• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 298  文章 - 377  trackbacks - 0
            <2017年12月>
            262728293012
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            常用鏈接

            留言簿(34)

            隨筆分類

            隨筆檔案

            文章檔案

            相冊

            收藏夾

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜



              (1)一些基本變量

            SOCKET HTTPSocket; // 主socket
            struct sockaddr_in SocketAddr; // address socket
            struct sockaddr_in BindSocket; // for bind


            int m_nRecvTimeout; // recieve timeout
            int m_nSendTimeout; // send timeout

            WSADATA wsaData;

            // 要下載文件部分。好像在BindSocket.sin_addr.s_addr = inet_addr (strHost);時,只能使用ip地址,所以了。。。

            // 如果誰知道更好的方法,別忘了告訴我一下。

            CString strHost="111.111.111.111 ";
            CString DownLoadAddress="http://www.aitenshi.com/bbs/images/";
            CString hostFile="logo.gif";
            int HttpPort=80;



              (2)一些函數,用來取得http頭,和獲取文件大小

            int GetFileLength(char *httpHeader)
            {
            CString strHeader;
            int local;
            strHeader=(CString)httpHeader;
            local=strHeader.Find("Content-Length",0);
            local+=16;
            strHeader.Delete(0,local);
            local=strHeader.Find("\r");
            strHeader.SetAt(local,'\0');

            char temp[30];
            strcpy(temp,strHeader.GetBuffer(strHeader.GetLength()));
            return atoi(temp);
            }

            int GetHttpHeader(SOCKET sckDest,char *str)
            {
            BOOL m_bResponsed=0;
            int m_nResponseHeaderSize;

            if(!m_bResponsed)
            {
            char c = 0;
            int nIndex = 0;
            BOOL bEndResponse = FALSE;
            while(!bEndResponse && nIndex < 1024)
            {
            recv(sckDest,&c,1,0);
            str[nIndex++] = c;
            if(nIndex >= 4)
            {
            if(str[nIndex - 4] == '\r' && str[nIndex - 3] == '\n'
            && str[nIndex - 2] == '\r' && str[nIndex - 1] == '\n')
            bEndResponse = TRUE;
            }
            }
            m_nResponseHeaderSize = nIndex;
            m_bResponsed = TRUE;
            }

            return m_nResponseHeaderSize;

            }


              (3)用來發送的部分

            void szcopy(char* dest,const char* src,int nMaxBytes)
            {
            int i_cntr=0;
            while ((src[i_cntr]!='\0')    (i_cntr dest[i_cntr]=src[i_cntr++];
            dest[i_cntr]='\0';
            }

            BOOL SocketSend(SOCKET sckDest,const char* szHttp)
            {

            char szSendHeader[MAXHEADERLENGTH];
            int iLen=strlen(szHttp);
            szcopy(szSendHeader,szHttp,iLen);
            if(send (sckDest ,(const char FAR *)szSendHeader ,iLen ,0)==SOCKET_ERROR)
            {
            closesocket(sckDest);
            AfxMessageBox("Error when send");
            return FALSE;
            }

            return TRUE;
            }

            BOOL SocketSend(SOCKET sckDest,CString szHttp)
            {

            int iLen=szHttp.GetLength();
            if(send (sckDest,szHttp,iLen,0)==SOCKET_ERROR)
            {
            closesocket(sckDest);
            AfxMessageBox("Error when send");
            return FALSE;
            }

            return TRUE;
            }


              (4)用于連接的函數

              這里是做了一些連接用的操作,分了兩種情況

              1)如果沒有使用代理,則直接連到你指定的計算機

              2)如果使用了代理,則直接連到代理

            BOOL CDLAngelDlg::ConnectHttp()
            {

            message="正在建立連接\n";


            UpdateData(TRUE);
            if(m_combo=="HTTP") // m_combo 一個下拉條
            {
            HTTPSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
            SocketAddr.sin_addr.s_addr = inet_addr (m_ProxyAddr);
            SocketAddr.sin_family=AF_INET;
            SocketAddr.sin_port=htons(atoi(m_Port));

            struct fd_set fdSet;
            struct timeval tmvTimeout={0L,0L};

            FD_ZERO(&fdSet);
            FD_SET(HTTPSocket, &fdSet);

            if (select(0,&fdSet,NULL,NULL,&tmvTimeout)==SOCKET_ERROR)
            {
            closesocket(HTTPSocket);
            AfxMessageBox("Error when select.");
            return 0;
            }


            if (connect(HTTPSocket, (const struct sockaddr *)&SocketAddr, sizeof(SocketAddr))==SOCKET_ERROR)
            {
            message="\n代理連接失敗\n";
            m_message.CleanText();
            m_message.AddText(message);
            return 0;
            }


            // 發送CONNCET請求令到代理服務器,用于和代理建立連接

            //代理服務器的地址和端口放在m_ProxyAddr,m_Port 里面

            CString temp;
            char tmpBuffer[1024];
            temp.Format("CONNECT %s:%s HTTP/1.1\r\nUser-Agent: MyApp/0.1\r\n\r\n",m_ProxyAddr,m_Port);
            if(!SocketSend(HTTPSocket,temp))
            {
            message="連接代理失敗";
            return 0;
            }

            // 取得代理響應,如果連接代理成功,代理服務器將返回200 Connection established

            GetHttpHeader(HTTPSocket,tmpBuffer);
            temp=tmpBuffer;
            if(temp.Find("HTTP/1.0 200 Connection established",0)==-1)
            {
            message="連接代理失敗\n";
            return 0;
            }

            message="代理連接完成\n";
            m_message.AddText("代理連接完成\n");
            return 1; // ----------〉這里是應該注意的,連接到代理后,就可以返回了,不需要再連接網上的另外一臺機,代理服務器會自動轉發數據,所以,連接完代理就像連接到網上另外一臺機一樣
            }

            // 這個,是為了給其他代理做準備
            else if(m_combo=="Socks4")
            {MessageBox("請注意,現在無法使用代理功能!");}
            else if(m_combo=="Socks5")
            {MessageBox("請注意,現在無法使用代理功能!");}


            // 如果沒有使用代理,就要連接到網上的另一臺機

            // 準備socket
            HTTPSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

            if (HTTPSocket==INVALID_SOCKET)
            {
            AfxMessageBox("Error when socket");
            return 0;
            }

            //設置超時
            struct linger zeroLinger;
            zeroLinger.l_onoff = 1;
            zeroLinger.l_linger = 0;
            if(setsockopt(HTTPSocket,SOL_SOCKET,SO_LINGER
            ,(const char *)&zeroLinger
            ,sizeof(zeroLinger))!=0)
            {
            closesocket(HTTPSocket);
            AfxMessageBox("Error when setscokopt(LINGER)");
            return 0;
            }
            //設置接收超時
            if(setsockopt(HTTPSocket,SOL_SOCKET,SO_RCVTIMEO
            ,(const char *)&m_nRecvTimeout
            ,sizeof(m_nRecvTimeout))!=0)
            {
            closesocket(HTTPSocket);
            AfxMessageBox("Error when setsockopt(RCVTIME).");
            return 0;
            }

            //設置發送超時
            if(setsockopt(HTTPSocket,SOL_SOCKET,SO_SNDTIMEO
            ,(const char *)&m_nSendTimeout
            ,sizeof(m_nSendTimeout))!=0)
            {
            closesocket(HTTPSocket);
            AfxMessageBox("Error when setsockopt(SNDTIMEO).");
            return 0;
            }


            SocketAddr.sin_addr.s_addr = htonl (INADDR_ANY);
            SocketAddr.sin_family=AF_INET;

            // 進行端口綁定
            if (bind (HTTPSocket,
            (const struct sockaddr FAR *)&SocketAddr,
            sizeof(SocketAddr))==SOCKET_ERROR)
            {
            closesocket(HTTPSocket);
            AfxMessageBox("Error when bind socket.");
            return 0;
            }

            //準備連接

            /// 準備連接信息
            BindSocket.sin_addr.s_addr = inet_addr (strHost);
            BindSocket.sin_family=AF_INET;
            BindSocket.sin_port=htons(HttpPort);


            struct fd_set fdSet;
            struct timeval tmvTimeout={0L,0L};

            FD_ZERO(&fdSet);
            FD_SET(HTTPSocket, &fdSet);

            if (select(0,&fdSet,NULL,NULL,&tmvTimeout)==SOCKET_ERROR)
            {
            closesocket(HTTPSocket);
            AfxMessageBox("Error when select.");
            return 0;
            }

            // 連接


            if (connect(HTTPSocket, (const struct sockaddr *)&BindSocket, sizeof(BindSocket))==SOCKET_ERROR)
            {
            AfxMessageBox("第一次連接失敗,準備第二次連接");
            if (connect(HTTPSocket
            ,(const struct sockaddr *)&BindSocket
            ,sizeof(BindSocket))==SOCKET_ERROR)
            {
            closesocket(HTTPSocket);
            AfxMessageBox("連接失敗");
            return 0;
            }

            }

            message="連接完成\n";

            return 1;
            }


              (5)發送http請求,為下載數據進行準備

            int CDLAngelDlg::SendHttpHeader()
            {
            //進行下載

            CString temp;
            BOOL bReturn;
            char tmpBuffer[MAXBLOCKSIZE];


            ///第1行:方法,請求的路徑,版本
            temp="GET "+DownLoadAddress+hostFile+" HTTP/1.0\r\n";
            bReturn=SocketSend(HTTPSocket,temp);
            if(!bReturn)
            {
            message="發送請求失敗";
            return 0;
            }


            ///第2行:主機
            temp="Host "+strHost+"\r\n";
            bReturn=SocketSend(HTTPSocket,temp);
            if(!bReturn)
            {
            message="發送請求失敗";
            return 0;
            }


            ///第3行:接收的數據類型
            bReturn=SocketSend(HTTPSocket,"Accept: */*\r\n");
            if(!bReturn)
            {
            message="發送請求失敗";
            return 0;
            }


            ///第4行:
            temp=DownLoadAddress;
            temp.Insert(0,"Referer ");
            temp+="\r\n";
            bReturn=SocketSend(HTTPSocket,temp);
            if(!bReturn)
            {
            message="發送請求失敗";
            return 0;
            }


            ///第5行:瀏覽器類型

            bReturn=SocketSend(HTTPSocket,"User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt; DTS Agent;)\r\n");
            if(!bReturn)
            {
            message="發送請求失敗";
            return 0;
            }

            ///第6行:連接設置,保持
            // SocketSend(HTTPSocket,"Connection:Keep-Alive\r\n");

            ///第7行:Cookie.

            bReturn=SocketSend(HTTPSocket,"Cache-Control: no-cache\r\n");
            if(!bReturn)
            {
            message="發送請求失敗";
            return 0;
            }


            bReturn=SocketSend(HTTPSocket,"Proxy-Connection: Keep-Alive\r\n");
            if(!bReturn)
            {
            message="發送請求失敗";
            return 0;
            }

            /// 續傳

            Range是要下載的數據范圍,對續傳很重要
            if(continueFlag)
            {
            temp.Format("Range: bytes=%d- \r\n",conLength);
            bReturn=SocketSend(HTTPSocket,temp);
            if(!bReturn)
            {
            message="發送請求失敗";
            return 0;
            }
            }


            ///最后一行:空行
            bReturn=SocketSend(HTTPSocket,"\r\n");
            if(!bReturn)
            {
            message="發送請求失敗";
            return 0;
            }

            ///取得http頭
            int i;
            i=GetHttpHeader(HTTPSocket,tmpBuffer);
            if(!i)
            {
            message="獲取HTTP頭出錯";
            return 0;
            }

            //如果取得的http頭含有404等字樣,則表示連接出問題
            temp=tmpBuffer;
            if(temp.Find("404")!=-1)
            {

            return 0;
            }

            // 得到待下載文件的大小

            filelength=GetFileLength(tmpBuffer);

            return 1;
            }


              這樣,就連接到網上的另一臺機了,如何下載數據,不用多說了吧

            while((num!=SOCKET_ERROR) && (num!=0))
            {
            num=recv (HTTPSocket
            ,(char FAR *)tmpBuffer
            ,(MAXBLOCKSIZE-1)
            ,0);


            file.Write(tmpBuffer,num);

            if(ExitFlag)
            {
            file.Close();
            closesocket(HTTPSocket);

            DownComplete=1;

            m_message.CleanText();
            m_message.ShowColorText(RGB(128,128,0),DLCompleteMes);

            m_progress.ShowWindow(SW_HIDE);
            m_stopDownload.ShowWindow(SW_HIDE);
            _endthread();
            }

            }

            posted on 2007-07-04 11:24 聶文龍 閱讀(3400) 評論(2)  編輯 收藏 引用 所屬分類: c++

            FeedBack:
            # re: 用VC++實現http代理 2007-08-08 21:54 聶文龍
            http代理源碼
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            #include <winsock2.h>
            #include <process.h>
            #include <windows.h>
            #include <assert.h>
            #define MAXBUFLEN 20480
            #define HTTPADDLEN 50
            #define TIMEWAIT 2000
            SOCKET Global[1000000];

            void DisplayBanner();
            void Proxy( void * pSocket);
            int ParseHttpRequest(char * SourceBuf,int DataLen,void * ServerAddr);
            void ParseError(char * ErrorMsg);

            int main(int argc,char * argv[])
            {
            SOCKET MainSocket,ClientSocket;
            struct sockaddr_in Host,Client;
            WSADATA WsaData;
            int AddLen,i;

            //初始化
            DisplayBanner();
            if(WSAStartup(MAKEWORD(2,2),&WsaData) < 0)
            {
            printf("dll load error\n");
            exit(-1);
            }
            //創建socket端口
            MainSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
            if(MainSocket == SOCKET_ERROR)
            {
            ParseError("端口創建錯誤");
            }
            Host.sin_family = AF_INET;
            Host.sin_port = htons(8080);
            Host.sin_addr.s_addr = inet_addr("159.226.39.116");
            printf("正在工作\n");
            //邦定
            if(bind(MainSocket,(SOCKADDR *)&Host,sizeof(Host)) != 0)
            {
            ParseError("邦定錯誤");
            }
            i = 0;
            //監聽
            if(listen(MainSocket,5) == SOCKET_ERROR)
            {
            ParseError("監聽錯誤");
            }
            AddLen = sizeof(Client);

            //連接新的客戶
            i = 0;
            while(1)
            {
            ClientSocket = accept(MainSocket,(SOCKADDR *)&Client,&AddLen);
            if(ClientSocket == SOCKET_ERROR)
            {
            ParseError("接受客戶請求錯誤");
            }
            printf(".");
            i ++ ;
            if( i >= 1000000)
            i = 0;
            Global[i] = ClientSocket;

            //對于每一個客戶啟動不同的進程進行控制
            //這個地方在使用ClientSocket的時候,要不要保證在某一時刻內只能有一個進程使用?
            _beginthread(Proxy,0,(void *)&Global[i]);

            }



            }
            void Proxy( void * pSocket)
            {
            SOCKET ClientSocket;
            char ReceiveBuf[MAXBUFLEN];
            int DataLen;
            struct sockaddr_in ServerAddr;
            SOCKET ProxySocket;
            int i = 0;
            int time = TIMEWAIT;

            //得到參數中的端口號信息
            ClientSocket = (SOCKET)* (SOCKET*)pSocket;
            //接受第一次請求信息
            memset(ReceiveBuf,0,MAXBUFLEN);
            DataLen = recv(ClientSocket,ReceiveBuf,MAXBUFLEN,0);

            if(DataLen == SOCKET_ERROR)
            {
            ParseError("錯誤\n");
            closesocket(ClientSocket);
            _endthread();
            }
            if(DataLen == 0)
            {
            closesocket(ClientSocket);
            _endthread();
            }
            //處理請求信息,分離出服務器地址
            if( ParseHttpRequest(ReceiveBuf,DataLen,(void *)&ServerAddr) < 0)
            {
            closesocket(ClientSocket);
            goto error;
            }
            //創建新的socket用來和服務器進行連接
            ProxySocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
            //設置超時時間
            setsockopt(ProxySocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&time,sizeof(time));
            if(ProxySocket == SOCKET_ERROR)
            {
            ParseError("端口創建錯誤");
            _endthread();
            }
            if(connect(ProxySocket,(SOCKADDR *)&ServerAddr,sizeof(ServerAddr)) == SOCKET_ERROR)
            {
            //ParseError("連接服務器錯誤");
            goto error;
            }
            //開始進行數據傳輸處理
            //發送到服務器端
            if(send(ProxySocket,ReceiveBuf,DataLen,0) == SOCKET_ERROR)
            {
            //ParseError("數據發送錯誤");
            goto error;

            }
            //從服務器端接受數據
            while(DataLen > 0)
            {
            memset(ReceiveBuf,0,MAXBUFLEN);

            if((DataLen = recv(ProxySocket,ReceiveBuf,MAXBUFLEN,0)) <= 0)
            {
            // ParseError("數據接受錯誤");
            break;

            }
            else
            //發送到客戶端
            if(send(ClientSocket,ReceiveBuf,DataLen,0) < 0)
            {
            // ParseError("數據發送錯誤");
            break;
            }

            }

            error:
            closesocket(ClientSocket);
            closesocket(ProxySocket);
            _endthread();
            return;

            }
            int ParseHttpRequest(char * SourceBuf,int DataLen,void * ServerAddr)
            {

            char * HttpHead = "http://";
            char * FirstLocation = NULL;
            char * LastLocation = NULL;
            char * PortLocation = NULL;
            char ServerName[HTTPADDLEN];
            char PortString[10];
            int NameLen;
            struct hostent * pHost;
            struct sockaddr_in * pServer = (struct sockaddr_in *)ServerAddr;
            //取得http://的位置
            FirstLocation = strstr(SourceBuf,HttpHead) + strlen(HttpHead);
            //取得/的位置
            LastLocation = strstr(FirstLocation,"/");

            //得到http://和/之間的服務器的名稱

            memset(ServerName,0,HTTPADDLEN);
            memcpy(ServerName,FirstLocation,LastLocation - FirstLocation);

            //有些情況下,請求的地址中帶有端口號格式為“:+ 端口號”;
            //取得 :的位置
            PortLocation = strstr(ServerName,":");


            //填充server結構
            pServer->sin_family = AF_INET;
            //在url中制定了服務器端口
            if(PortLocation != NULL)
            {
            NameLen = PortLocation - ServerName -1;
            memset(PortString,0,10);
            memcpy(PortString,PortLocation + 1,NameLen);
            pServer->sin_port = htons((u_short)atoi(PortString));
            *PortLocation = 0;
            }
            else//在url中,沒有制定服務器端口
            {
            pServer->sin_port = htons(80);
            }

            if(NameLen > HTTPADDLEN)
            {
            ParseError("服務器名字太長");
            return -1;
            }

            //得到服務器信息
            //如果地址信息是以IP地址(202.194.7.1)的形式出現的
            if(ServerName[0] >= '0' && ServerName[0] <= '9')
            {

            pServer->sin_addr.s_addr = inet_addr(ServerName);
            }
            //以域名的形式出現的(www.sina.com.cn)
            else
            {
            pHost = (struct hostent *)gethostbyname(ServerName);
            if(!pHost)
            {
            printf("取得主機信息錯誤\n");
            printf("%s\n",ServerName);
            return -1;
            }
            memcpy(&pServer->sin_addr,pHost->h_addr_list[0],sizeof(pServer->sin_addr));
            }

            return 0;
            }
            void ParseError(char * ErrorMsg)
            {
            // printf("%s %d\n",ErrorMsg,GetLastError());
            // WSACleanup();
            // exit(-1);
            }
            void DisplayBanner()
            {
            printf("=================================================\n");
            printf("==== ====\n");
            printf("==== HTTP PROXY v2.0 ====\n");
            printf("==== ====\n");
            printf("=================================================\n");
            }



              回復  更多評論
              
            # re: 用VC++實現http代理 2007-08-08 22:56 聶文龍
            #include "stdafx.h"
            #include "Proxy.h"
            #include < winsock2.h > //WINSOCKET API 2。0
            #include < stdlib.h >
            #include < stdio.h >
            #include < string.h >

            #ifdef _DEBUG
            #define new DEBUG_NEW
            #undef THIS_FILE
            static char THIS_FILE[] = __FILE__;
            #endif

            /////////////////////////////////////////////////////////////////////////////


            #define HTTP "http://"
            #define FTP "ftp://"
            #define PROXYPORT 5001 //Proxy 端口
            #define BUFSIZE 10240 //緩沖區大小


            CWinApp theApp;

            using namespace std;

            UINT ProxyToServer(LPVOID pParam);
            UINT UserToProxyThread(void *pParam);

            struct SocketPair{
            SOCKET user_proxy; //socket : 本地機器到PROXY 服務機
            SOCKET proxy_server; //socket : PROXY 服務機到遠程主機
            BOOL IsUser_ProxyClosed; // 本地機器到PROXY 服務機狀態
            BOOL IsProxy_ServerClosed; // PROXY 服務機到遠程主機狀態
            };


            struct ProxyParam{
            char Address[256]; // 遠程主機地址
            HANDLE User_SvrOK; // PROXY 服務機到遠程主機的聯結狀態
            SocketPair *pPair; // 維護一組SOCKET的指針
            int Port; // 用來聯結遠程主機的端口
            }; //這個結構用來PROXY SERVER與遠程主機的信息交換.

            SOCKET gListen_Socket; //用來偵聽的SOCKET。

            int StartServer() //啟動服務
            {
            WSADATA wsaData;
            sockaddr_in local;
            SOCKET listen_socket;

            if(::WSAStartup(0x202,&wsaData)!=0)
            {printf("\nError in Startup session.\n");WSACleanup();return -1;};

            local.sin_family=AF_INET;
            local.sin_addr.s_addr=INADDR_ANY;
            local.sin_port=htons(PROXYPORT);

            listen_socket=socket(AF_INET,SOCK_STREAM,0);
            if(listen_socket==INVALID_SOCKET)
            {printf("\nError in New a Socket.");WSACleanup();return -2;}

            if(::bind(listen_socket,(sockaddr *)&local,sizeof(local))!=0)
            {printf("\n Error in Binding socket."); WSACleanup();return -3; };

            if(::listen(listen_socket,5)!=0)
            {printf("\n Error in Listen."); WSACleanup(); return -4;}
            gListen_Socket=listen_socket;
            AfxBeginThread(UserToProxyThread,NULL); //啟動偵聽
            return 1;
            }

            int CloseServer() //關閉服務
            {
            closesocket(gListen_Socket);
            WSACleanup();
            return 1;
            }
            //分析接收到的字符,得到遠程主機地址

            int GetAddressAndPort( char * str, char *address, int * port)
            {
            char buf[BUFSIZE], command[512], proto[128], *p;
            int j;
            sscanf(str,"%s%s%s",command,buf,proto);
            p=strstr(buf,HTTP);
            //HTTP
            if(p)
            {
            p+=strlen(HTTP);
            for(int i=0;i< strlen(p);i++)
            if( *(p+i)=='/') break;
            *(p+i)=0;
            strcpy(address,p);
            p=strstr(str,HTTP);
            for(int j=0;j< i+strlen(HTTP);j++)
            *(p+j)=' '; //去掉遠程主機名: GET http:/www.csdn.net/ HTTP1.1 == > GET / HTTP1.1
            *port=80; //缺省的 http 端口
            }
            else
            {//FTP, 不支持, 下面的代碼可以省略.
            p=strstr(buf,FTP);
            if(!p) return 0;
            p+=strlen(FTP);
            for(int i=0;i< strlen(p);i++)
            if( *(p+i)=='/') break; //Get The Remote Host
            *(p+i)=0;
            for(j=0;j< strlen(p);j++)
            if(*(p+j)==':')
            {*port=atoi(p+j+1); //Get The Port
            *(p+j)=0;
            }
            else *port=21;

            strcpy(address,p);
            p=strstr(str,FTP);
            for(j=0;j< i+strlen(FTP);j++)
            *(p+j)=' ';
            }
            return 1;
            }

            // 取到本地的數據,發往遠程主機
            UINT UserToProxyThread(void *pParam)
            {
            char Buffer[BUFSIZE];
            int Len;
            sockaddr_in from;
            SOCKET msg_socket;
            int fromlen,retval;
            SocketPair SPair;
            ProxyParam ProxyP;
            CWinThread *pChildThread;
            fromlen=sizeof(from);
            msg_socket=accept(gListen_Socket,(struct sockaddr*)&from,&fromlen);
            AfxBeginThread(UserToProxyThread,pParam); //啟動另一偵聽.
            if( msg_socket==INVALID_SOCKET)
            { printf( "\nError in accept "); return -5;}
            //讀客戶的第一行數據

            SPair.IsUser_ProxyClosed=FALSE;
            SPair.IsProxy_ServerClosed=TRUE;
            SPair.user_proxy=msg_socket;

            retval=recv(SPair.user_proxy,Buffer,sizeof(Buffer),0);

            if(retval==SOCKET_ERROR)
            { printf("\nError Recv");
            if(SPair.IsUser_ProxyClosed==FALSE)
            {closesocket(SPair.user_proxy);
            SPair.IsUser_ProxyClosed=TRUE;
            }
            }
            if(retval==0)
            {printf("Client Close connection\n");
            if(SPair.IsUser_ProxyClosed==FALSE)
            {closesocket(SPair.user_proxy);
            SPair.IsUser_ProxyClosed=TRUE;
            }
            }
            Len=retval;
            #ifdef _DEBUG

            Buffer[Len]=0;
            printf("\n Received %d bytes,data[%s]from client\n",retval,Buffer);
            #endif
            //
            SPair.IsUser_ProxyClosed=FALSE;
            SPair.IsProxy_ServerClosed=TRUE;
            SPair.user_proxy=msg_socket;

            ProxyP.pPair=&SPair;
            ProxyP.User_SvrOK=CreateEvent(NULL,TRUE,FALSE,NULL);

            GetAddressAndPort( Buffer,ProxyP.Address,&ProxyP.Port);

            pChildThread=AfxBeginThread(ProxyToServer,(LPVOID)&ProxyP);
            ::WaitForSingleObject(ProxyP.User_SvrOK,60000); //等待聯結
            ::CloseHandle(ProxyP.User_SvrOK);

            while(SPair.IsProxy_ServerClosed ==FALSE && SPair.IsUser_ProxyClosed==FALSE)
            {
            retval=send(SPair.proxy_server,Buffer,Len,0);
            if(retval==SOCKET_ERROR)
            { printf("\n send() failed:error%d\n",WSAGetLastError());
            if(SPair.IsProxy_ServerClosed==FALSE)
            {
            closesocket(SPair.proxy_server);
            SPair.IsProxy_ServerClosed=TRUE;
            }
            continue;
            }
            retval=recv(SPair.user_proxy,Buffer,sizeof(Buffer),0);

            if(retval==SOCKET_ERROR)
            { printf("\nError Recv");
            if(SPair.IsUser_ProxyClosed==FALSE)
            {closesocket(SPair.user_proxy);
            SPair.IsUser_ProxyClosed=TRUE;
            }
            continue;
            }
            if(retval==0)
            {printf("Client Close connection\n");
            if(SPair.IsUser_ProxyClosed==FALSE)
            {closesocket(SPair.user_proxy);
            SPair.IsUser_ProxyClosed=TRUE;
            }
            break;
            }
            Len=retval;
            #ifdef _DEBUG
            Buffer[Len]=0;
            printf("\n Received %d bytes,data[%s]from client\n",retval,Buffer);
            #endif

            } //End While

            if(SPair.IsProxy_ServerClosed==FALSE)
            {
            closesocket(SPair.proxy_server);
            SPair.IsProxy_ServerClosed=TRUE;
            }
            if(SPair.IsUser_ProxyClosed==FALSE)
            {closesocket(SPair.user_proxy);
            SPair.IsUser_ProxyClosed=TRUE;
            }
            ::WaitForSingleObject(pChildThread- >m_hThread,20000); //Should check the return value
            return 0;
            }
            // 讀取遠程主機數據,并發往本地客戶機
            UINT ProxyToServer(LPVOID pParam){
            ProxyParam * pPar=(ProxyParam*)pParam;
            char Buffer[BUFSIZE];
            char *server_name= "localhost";
            unsigned short port ;
            int retval,Len;
            unsigned int addr;
            int socket_type ;
            struct sockaddr_in server;
            struct hostent *hp;
            SOCKET conn_socket;

            socket_type = SOCK_STREAM;
            server_name = pPar- >Address;
            port = pPar- >Port;

            if (isalpha(server_name[0])) { /* server address is a name */
            hp = gethostbyname(server_name);
            }
            else { /* Convert nnn.nnn address to a usable one */
            addr = inet_addr(server_name);
            hp = gethostbyaddr((char *)&addr,4,AF_INET);
            }
            if (hp == NULL ) {
            fprintf(stderr,"Client: Cannot resolve address [%s]: Error %d\n",
            server_name,WSAGetLastError());
            ::SetEvent(pPar- >User_SvrOK);
            return 0;
            }

            //
            // Copy the resolved information into the sockaddr_in structure
            //
            memset(&server,0,sizeof(server));
            memcpy(&(server.sin_addr),hp- >h_addr,hp- >h_length);
            server.sin_family = hp- >h_addrtype;
            server.sin_port = htons(port);

            conn_socket = socket(AF_INET,socket_type,0); /* 打開一個 socket */
            if (conn_socket < 0 ) {
            fprintf(stderr,"Client: Error Opening socket: Error %d\n",
            WSAGetLastError());
            pPar- >pPair- >IsProxy_ServerClosed=TRUE;
            ::SetEvent(pPar- >User_SvrOK);
            return -1;
            }
            #ifdef _DEBUG
            printf("Client connecting to: %s\n",hp- >h_name);
            #endif
            if (connect(conn_socket,(struct sockaddr*)&server,sizeof(server))
            == SOCKET_ERROR) {
            fprintf(stderr,"connect() failed: %d\n",WSAGetLastError());
            pPar- >pPair- >IsProxy_ServerClosed=TRUE;
            ::SetEvent(pPar- >User_SvrOK);
            return -1;
            }
            pPar- >pPair- >proxy_server=conn_socket;
            pPar- >pPair- >IsProxy_ServerClosed=FALSE;
            ::SetEvent(pPar- >User_SvrOK);
            // cook up a string to send
            while(!pPar- >pPair- >IsProxy_ServerClosed &&!pPar- >pPair- >IsUser_ProxyClosed)
            {
            retval = recv(conn_socket,Buffer,sizeof (Buffer),0 );
            if (retval == SOCKET_ERROR ) {
            fprintf(stderr,"recv() failed: error %d\n",WSAGetLastError());
            closesocket(conn_socket);
            pPar- >pPair- >IsProxy_ServerClosed=TRUE;
            break;
            }
            Len=retval;
            if (retval == 0) {
            printf("Server closed connection\n");
            closesocket(conn_socket);
            pPar- >pPair- >IsProxy_ServerClosed=TRUE;
            break;
            }

            retval = send(pPar- >pPair- >user_proxy,Buffer,Len,0);
            if (retval == SOCKET_ERROR) {
            fprintf(stderr,"send() failed: error %d\n",WSAGetLastError());
            closesocket(pPar- >pPair- >user_proxy);
            pPar- >pPair- >IsUser_ProxyClosed=TRUE;
            break;
            }
            #ifdef _DEBUG
            Buffer[Len]=0;
            printf("Received %d bytes, data [%s] from server\n",retval,Buffer);
            #endif
            }
            if(pPar- >pPair- >IsProxy_ServerClosed==FALSE)
            {
            closesocket(pPar- >pPair- >proxy_server);
            pPar- >pPair- >IsProxy_ServerClosed=TRUE;
            }
            if(pPar- >pPair- >IsUser_ProxyClosed==FALSE)
            {closesocket(pPar- >pPair- >user_proxy);
            pPar- >pPair- >IsUser_ProxyClosed=TRUE;
            }
            return 1;
            }



            int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
            {
            int nRetCode = 0;

            // 初始化SOCKET
            if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
            {
            // 錯誤處理
            cerr < < _T("Fatal Error: MFC initialization failed") < < endl;
            nRetCode = 1;
            }
            else
            {
            // 主程序開始.
            StartServer();
            while(1)
            if(getchar()=='q') break;
            CloseServer();
            }

            return nRetCode;
            }


              回復  更多評論
              
            久久综合九色综合久99| 亚洲AV乱码久久精品蜜桃| 国产精品久久久久久久午夜片 | aaa级精品久久久国产片| 国产亚洲欧美精品久久久| 亚洲午夜久久影院| 国色天香久久久久久久小说| 精品久久久久香蕉网| 香港aa三级久久三级老师2021国产三级精品三级在 | A级毛片无码久久精品免费| 伊人久久精品影院| 国产精品久久久久久久久鸭| 亚洲国产精品无码久久久久久曰| 欧美丰满熟妇BBB久久久| 久久精品中文字幕第23页| 99久久er这里只有精品18| 人妻系列无码专区久久五月天| 无码人妻精品一区二区三区久久久| 国产成人99久久亚洲综合精品 | 99久久久久| 国产高潮国产高潮久久久| 久久久久亚洲av综合波多野结衣| 91精品国产91久久久久久蜜臀| 人妻精品久久无码区| 久久国产免费直播| 性欧美大战久久久久久久| 久久99精品久久久久久齐齐| 精品久久香蕉国产线看观看亚洲| 亚洲精品乱码久久久久久按摩| 综合久久一区二区三区 | 久久精品成人免费网站| 久久久久高潮毛片免费全部播放| 久久精品综合网| 久久精品国产2020| 亚洲精品乱码久久久久久| 色偷偷88888欧美精品久久久| 久久精品国产亚洲av麻豆图片| 久久精品青青草原伊人| 色综合久久久久无码专区| 精品久久久久久无码专区| 日韩一区二区久久久久久 |