首页
社区
课程
招聘
iocp socks5源码
发表于: 2006-4-11 15:27 8487

iocp socks5源码

2006-4-11 15:27
8487
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32")

#pragma warning(disable: 4312)

DWORD WINAPI ServerWorkerThread(LPVOID lpParameter);

#define IOSend                        1000
#define IORecv                        2000

struct TCPHANDLE
{
        SOCKET Sousockid;
        SOCKET Desockid;
};

struct IODATA
{
        struct
        {
                WSAOVERLAPPED Overlapped;
                DWORD Operation;
                WSABUF buf;
                char databuf[1024];
        }Sou;
       
        struct
        {
                WSAOVERLAPPED Overlapped;
                DWORD Operation;
                WSABUF buf;
                char databuf[1024];
        }De;
};

void main()
{
        WSADATA wsaData;
        WSAStartup(0x202,&wsaData);

        HANDLE CompetionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);

        SYSTEM_INFO SystenInfo;
        GetSystemInfo(&SystenInfo);

        for(int i=0;i<SystenInfo.dwNumberOfProcessors*2;i++)
        {
                CloseHandle(CreateThread(NULL,0,ServerWorkerThread,CompetionPort,0,NULL));
        }

        SOCKET Listen = socket(AF_INET,SOCK_STREAM,0);

        sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_addr.S_un.S_addr = INADDR_ANY;
        addr.sin_port = htons(1080);

        bind(Listen,(sockaddr*)&addr,sizeof(addr));

        listen(Listen,5);

        TCPHANDLE *tcphandle;
        IODATA *iodata;
        DWORD Flags;
        DWORD RecvBytes;

        while(TRUE)
        {
                SOCKET Accept = accept(Listen,NULL,NULL);

                tcphandle = (TCPHANDLE *)GlobalAlloc(GPTR,sizeof(TCPHANDLE));
                tcphandle->Sousockid = Accept;
                CreateIoCompletionPort((HANDLE)Accept,CompetionPort,(DWORD)tcphandle,0);

                iodata = (IODATA *)GlobalAlloc(GPTR,sizeof(IODATA));

                iodata->Sou.buf.buf = iodata->Sou.databuf;
                iodata->Sou.buf.len = sizeof(iodata->Sou.databuf);
                iodata->Sou.Operation = IORecv;

                Flags = 0;
                WSARecv(tcphandle->Sousockid,&iodata->Sou.buf,1,&RecvBytes,&Flags,&iodata->Sou.Overlapped,NULL);
        }
}

DWORD WINAPI ServerWorkerThread(LPVOID lpParameter)
{
        DWORD BytesTransferred;
        DWORD SendBytes;
        DWORD RecvBytes;
        DWORD Flags;
        DWORD Handle;

        IODATA *iodata;
        TCPHANDLE *tcphandle;

        while(TRUE)
        {
                GetQueuedCompletionStatus((HANDLE)lpParameter,&BytesTransferred,&Handle,(LPOVERLAPPED*)&iodata,INFINITE);

                if (BytesTransferred == 0)
                {
                        closesocket(((TCPHANDLE*)Handle)->Sousockid);;

                        GlobalFree((HGLOBAL)Handle);
                        GlobalFree(iodata);
                        continue;
                }

                int SockType;
                int SockTypelen = sizeof(SockType);
                getsockopt(((TCPHANDLE*)Handle)->Sousockid,SOL_SOCKET,SO_TYPE,(char*)&SockType,&SockTypelen);

                switch(SockType)
                {
                case SOCK_STREAM:
                        {
                                switch(iodata->Sou.Operation)
                                {
                                case IOSend:
                                        {
                                                if (iodata->Sou.buf.len - BytesTransferred != 0)
                                                {
                                                        ZeroMemory(&iodata->Sou.Overlapped,sizeof(iodata->Sou.Overlapped));

                                                        iodata->Sou.buf.buf += BytesTransferred;
                                                        iodata->Sou.buf.len -= BytesTransferred;

                                                        if (SOCKET_ERROR == WSASend(((TCPHANDLE*)Handle)->Sousockid,&iodata->Sou.buf,1,&SendBytes,0,&iodata->Sou.Overlapped,NULL))
                                                        {
                                                                if (WSAGetLastError() != WSA_IO_PENDING)
                                                                {
                                                                        closesocket(((TCPHANDLE*)Handle)->Sousockid);

                                                                        GlobalFree((HGLOBAL)Handle);
                                                                        GlobalFree(iodata);
                                                                        continue;
                                                                }
                                                        }
                                                }

                                                break;
                                        }
                                case IORecv:
                                        {
                                                ZeroMemory(&iodata->Sou.Overlapped,sizeof(iodata->Sou.Overlapped));
                                                ZeroMemory(&iodata->De.Overlapped,sizeof(iodata->De.Overlapped));

                                                if (iodata->Sou.databuf[0] == 5 && iodata->Sou.databuf[1] == 1  && iodata->Sou.databuf[2] == 0 && BytesTransferred == 3)
                                                {
                                                        iodata->De.databuf[0] = 5;
                                                        iodata->De.databuf[1] = 0;

                                                        iodata->De.buf.buf = iodata->De.databuf;
                                                        iodata->De.buf.len = 2;
                                                        iodata->De.Operation = IOSend;

                                                        if (SOCKET_ERROR == WSASend(((TCPHANDLE*)Handle)->Sousockid,&iodata->De.buf,1,&SendBytes,0,&iodata->De.Overlapped,NULL))
                                                        {
                                                                if (WSAGetLastError() != WSA_IO_PENDING)
                                                                {
                                                                        closesocket(((TCPHANDLE*)Handle)->Sousockid);

                                                                        GlobalFree((HGLOBAL)Handle);
                                                                        GlobalFree(iodata);
                                                                        continue;
                                                                }
                                                        }
                                                }
                                                else if (iodata->Sou.databuf[0] == 5 && iodata->Sou.databuf[1] == 1 && iodata->Sou.databuf[2] == 0 && iodata->Sou.databuf[3] == 1)
                                                {
                                                        tcphandle = (TCPHANDLE *)GlobalAlloc(GPTR,sizeof(TCPHANDLE));

                                                        tcphandle->Sousockid = socket(AF_INET,SOCK_STREAM,0);
                                                        tcphandle->Desockid = ((TCPHANDLE*)Handle)->Sousockid;

                                                        ((TCPHANDLE*)Handle)->Desockid = tcphandle->Sousockid;

                                                        sockaddr_in addr;
                                                        addr.sin_family = AF_INET;
                                                        CopyMemory(&addr.sin_addr,&iodata->Sou.databuf[4],4);
                                                        CopyMemory(&addr.sin_port,&iodata->Sou.databuf[8],2);

                                                        bind(tcphandle->Sousockid,(sockaddr*)&addr,sizeof(addr));

                                                        DWORD time = GetTickCount();
                                                        if (SOCKET_ERROR == connect(tcphandle->Sousockid,(sockaddr*)&addr,sizeof(addr)))
                                                        {
                                                                Sleep(1);
                                                        }

                                                        if (GetTickCount()-time > 1000)
                                                        {
                                                                printf("连接耗时%d毫秒\n",GetTickCount()-time);
                                                        }

                                                        if (NULL == CreateIoCompletionPort((HANDLE)tcphandle->Sousockid,(HANDLE)lpParameter,(DWORD)tcphandle,0))
                                                        {
                                                                Sleep(1);
                                                        }

                                                        IODATA *otheriodata = (IODATA *)GlobalAlloc(GPTR,sizeof(IODATA));

                                                        otheriodata->Sou.buf.buf = otheriodata->Sou.databuf;
                                                        otheriodata->Sou.buf.len = sizeof(otheriodata->Sou.databuf);
                                                        otheriodata->Sou.Operation = IORecv;

                                                        Flags = 0;
                                                        if (SOCKET_ERROR == WSARecv(tcphandle->Sousockid,&otheriodata->Sou.buf,1,&RecvBytes,&Flags,&otheriodata->Sou.Overlapped,NULL))
                                                        {
                                                                if (WSAGetLastError() != WSA_IO_PENDING)
                                                                {
                                                                        closesocket(tcphandle->Sousockid);

                                                                        GlobalFree(tcphandle);
                                                                        GlobalFree(otheriodata);
                                                                        continue;
                                                                }
                                                        }

                                                        iodata->De.databuf[0] = 5;
                                                        iodata->De.databuf[1] = 0;
                                                        iodata->De.databuf[2] = 0;
                                                        iodata->De.databuf[3] = 1;

                                                        sockaddr_in localaddr;
                                                        int localaddrlen = sizeof(localaddr);
                                                        getsockname(((TCPHANDLE*)Handle)->Sousockid,(sockaddr*)&localaddr,&localaddrlen);

                                                        CopyMemory(&iodata->De.databuf[4],&localaddr.sin_addr,4);
                                                        CopyMemory(&iodata->De.databuf[8],&localaddr.sin_port,2);

                                                        iodata->De.buf.buf = iodata->De.databuf;
                                                        iodata->De.buf.len = 10;
                                                        iodata->De.Operation = IOSend;

                                                        if(SOCKET_ERROR == WSASend(((TCPHANDLE*)Handle)->Sousockid,&iodata->De.buf,1,&SendBytes,0,&iodata->De.Overlapped,NULL))
                                                        {
                                                                if (WSAGetLastError() != WSA_IO_PENDING)
                                                                {
                                                                        closesocket(((TCPHANDLE*)Handle)->Sousockid);

                                                                        GlobalFree((HGLOBAL)Handle);
                                                                        GlobalFree(iodata);
                                                                        continue;
                                                                }
                                                        }
                                                }
                                                else
                                                {
                                                        CopyMemory(iodata->De.databuf,iodata->Sou.databuf,BytesTransferred);

                                                        iodata->De.buf.buf = iodata->De.databuf;
                                                        iodata->De.buf.len = BytesTransferred;
                                                        iodata->De.Operation = IOSend;

                                                        if (SOCKET_ERROR == WSASend(((TCPHANDLE*)Handle)->Desockid,&iodata->De.buf,1,&SendBytes,0,&iodata->De.Overlapped,NULL))
                                                        {
                                                                if (WSAGetLastError() != WSA_IO_PENDING)
                                                                {
                                                                        DWORD ret = WSAGetLastError();        //10038
                                                                        closesocket(((TCPHANDLE*)Handle)->Sousockid);

                                                                        GlobalFree((HGLOBAL)Handle);
                                                                        GlobalFree(iodata);
                                                                        continue;
                                                                }
                                                        }
                                                }

                                                iodata->Sou.buf.buf = iodata->Sou.databuf;
                                                iodata->Sou.buf.len = sizeof(iodata->Sou.databuf);
                                                iodata->Sou.Operation = IORecv;

                                                Flags = 0;
                                                if (SOCKET_ERROR == WSARecv(((TCPHANDLE*)Handle)->Sousockid,&iodata->Sou.buf,1,&RecvBytes,&Flags,&iodata->Sou.Overlapped,NULL))
                                                {
                                                        if (WSAGetLastError() != WSA_IO_PENDING)
                                                        {
                                                                DWORD ret = WSAGetLastError();
                                                                closesocket(((TCPHANDLE*)Handle)->Sousockid);

                                                                GlobalFree((HGLOBAL)Handle);
                                                                GlobalFree(iodata);
                                                                continue;
                                                        }
                                                }

                                                break;
                                        }
                                }
                                break;
                        }
                case SOCK_DGRAM:
                        {
                                break;
                        }
                }

        }

        return 0;
}

程序存在一些小问题~~
希望高手可以指出来~~~

我一直没有检查到哪里有问题~~~~

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (5)
雪    币: 212
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
没有处理粘包,另外大流量的时候会乱序
2006-4-14 13:07
0
雪    币: 1272
活跃值: (746)
能力值: ( LV13,RANK:810 )
在线值:
发帖
回帖
粉丝
3
个人感觉用完成端口来作代理之类的程序有点不可是.
Win9x下就有点问题喽..
线程池没作好.大量数据包也不会有好结果.
不过学习与参考的价值颇高
2006-4-14 17:28
0
雪    币: 235
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
我想要知道改程序的具体缺陷在什么地方~~~

不考虑9x
2006-4-14 17:53
0
雪    币: 235
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
当然connect这个地方也有缺陷,如果几个工作线程同时执行connect函数,并且需要连接的地址无效,或者很慢的情况下,会导致整个程序的效率下降~~

这个是后续可以优化的~~

目前的问题是,程序存在崩溃的问题,而且没有找到导致崩溃的原因再哪里
2006-4-14 17:56
0
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
6
可以给一点注释和讲解么,
对这块不是很了解
2006-4-15 16:41
0
游客
登录 | 注册 方可回帖
返回
//