荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: michaelx (好好学习), 信区: Program
标  题: 為你的QQ造一個SOCK5 PROXY(Gcc篇)
发信站: 荔园晨风BBS站 (Fri Mar 28 18:57:59 2003), 站内信件

作者: 趙氏軟體(http://chiosoft.51.net)
E-mail: chiosoft@163.net
※轉貼請注明出處※


本文以QQ為對像,教你如何寫一個SOCK5 PROXY

一、準備工作
===================
1.編譯器:
為提高程序的可移植性和避免MS秋後算帳,本文將使用GCC作為編譯器,Win32版的
GCC可到www.mingw.org下載,或者用Dev-C++自帶的GCC也行.

2.程序運行環境:
可在Windows 2000/XP和LINUX下運行,Win9x系統沒試過,不知行不行.

3.如何編譯:
在LINUX下用 gcc mysock5.c -o mysock5
在Win32下用 gcc mysock5.c -o mysock5.exe -lwsock32
其中一定要加參數-lwsock32來指明使用Windows Socket相關的庫,否則連結時會出
錯,在Linux下編譯不用.


二、基本思路
===================
Proxy是什麼?我想不用我多說吧,還是馬上進入正題吧.SOCK5是一種Proxy協議,支
持TCP和UDP協議,也是QQ唯一支持的Proxy類型,詳情可參閱rfc1928.txt.

1.握手過程
客戶程序要使用PROXY服務,首先要跟PROXY SERVER進行握手,這個過程是基於
TCP/IP協議.

2.資料傳輸
QQ是使用UDP來傳送資料的,所以當QQ和SOCK5 PROXY握手成功後,就會轉向連接一個
UDP SOCKET,也就是說我們這個程序首先要建立一個TCP SOCKET和QQ進行握手,然後
再要建立一個UDP SOCKET來進行數據中轉,實現代理服務的功能.

這是一個最簡單的PROXY,只支持一個用戶連接一次,連接中止後需退出重新啟動.



三、程序框架
===================
先看看源代碼mysock5.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

//Windows和LINUX系統所提供的Socket API不一樣,需要分別聲明
#ifdef _WIN32
#include <winsock2.h>
#include <wininet.h>
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif

//定義一段緩衝區
#define BUFSZ   65535
char buf[ BUFSZ ];

int main(int argc, char** argv)
{
        //這是Server的資料,包括IP地址以及用作TCP和UDP連接的端口號
        short tcp_proxy_port=8888, udp_proxy_port=8811;
        char udp_proxy_ip[]="127.0.0.1";
        short clt_udp_port;

        //在Windows系統下,使用網絡前要先用WSAStartup()來進行初始化,
        //WSA是Windows Socket API的意思,本文使用WinSock 2.0版本
        //在VC中可以用WINSOCK_VERSION來指定版本,不過GCC FOR WIN32沒有定義這個宏

        //我們需要自己指定
        #ifdef _WIN32
        WSADATA WSAData;
        if( WSAStartup(0x0110, &WSAData) ) {
        //if( WSAStartup(WINSOCK_VERSION, &WSAData) ) {
                p_error("WSA error");
                exit(-1);
        }
        #endif


        //啟動一個TCP SOCKET,用來和QQ進行握手,並記錄QQ用來和我們溝通的UDP端口號
(clt_udp_port)
        Launch_TCP( tcp_proxy_port, udp_proxy_ip, udp_proxy_port, &clt_udp_port
 );

        //握手成功後,啟動一個UDP SOCKET,用作數據傳輸,是真正起PROXY作用的部份
        Launch_UDP( udp_proxy_port, udp_proxy_ip, clt_udp_port );

        return 0;
}





四、工具函數
===================
正所謂工欲善其事,必先利其器,好的程序當然不能缺乏好的工具函數,有了這些函
數,進行調試就更加方便了.

1. p_error
這是一個處理錯誤信息的函數,把所有的錯誤信息集中用一個函數來處理是一個好
習慣,目前我們直接用printf()將其輸出,當然也可以輸出到文件或者干脆把它忽略
:)

void p_error( const char *err_msg )
{
        printf( "ERR=>%s\n", err_msg );
}




2. debug_showbin
用來輸出一段數據的內容(16進制)

void debug_showbin( const char *dbuf, int n, const char *name, const
char *end )
{
        int i;

        printf( "%s ==> %d bytes: ", name, n );

        for( i=0; i<n; i++ )
                printf( "(0x%x)", (unsigned char)dbuf[i] );

        printf( "%s", end );
}




3. debug_showip
用來顯示sockaddr_in類型數據中的IP和Port

void debug_showip( const struct sockaddr_in *dbuf, const char *name,
const char *end )
{
        printf("[ %s ==> %s:%u ]%s", name, inet_ntoa(dbuf->sin_addr),
ntohs(dbuf->sin_port), end

);
}




五、測試
===================
下載源代碼後可嘗試編譯,然後執行,看看有沒有錯誤信息:)

--

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 220.112.3.40]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店