分享
 
 
 

一个简易的UDP Proxy程序

王朝other·作者佚名  2006-11-23
窄屏简体版  字體: |||超大  

一个简易的UDP Proxy程序

作为<<一个简易的proxy程序的开发过程>>的补充

1、为什么开发这个UDP程序

网络状况如上文<<一个简易的proxy程序的开发过程>>。我们的socks代理是有权限的(相信很多公司

都有这种情况存在)。写这个程序的时候,我还没有socks代理的权限,所以不能上OICQ。这让我感到

很不方便。所以,我决定写一个UDP的代理程序来实现我上OICQ的愿望。原理同上文是一样的。只是在

具体实现上略有所不同。

先看看源代码,稍后再来解释。(由于这个版本是一个完全功能版,所以提供了很多sp.c没有提供的功

能。)上文中提到过的部分,这里就不再次一一解释了。

-----------------------------------------------------------------------------------------

/***************************************************

Program: pu.c

Description: a smart UDP proxy

Author: Alan Chen ( ariesram@may10.ca )

Date: Dec 1, 2000

***************************************************/

#include

#include

#include

#include

#include

#include

#include

#include

#define MAX_ID_LEN 12

#define LOGFILE "/usr/tmp/.pu.log"

#define ERRLOG "/usr/tmp/.pu.err"

void sig_int(int sig);

void do_receive(int fd_tran);

void p_error(const char * err_msg);

void p_log(const char * buffer, int len);

int

main(int argc, char ** argv)

{

int fd_listen, fd_tran;

struct sockaddr_in sin, out;

struct sockaddr_in r_in, r_out;

struct sockaddr_in stmp;

int port = 1250;

int pid;

char * ip;

int i;

fd_set fdset;

char buffer[2048*2];

int data_len, alen;

struct timeval val;

#ifndef _DEBUG

signal(SIGINT, SIG_IGN);

#endif

signal(SIGHUP, SIG_IGN);

/* signal(SIGTERM, SIG_IGN); */

signal(SIGABRT, SIG_IGN);

signal(SIGSTOP, SIG_IGN);

signal(SIGCHLD, SIG_IGN);

#ifndef _DEBUG

if (fork() != 0)

exit(0);

setsid();

for (i = 256; i >= 0; i --)

#endif

#ifdef _DEBUG

for (i = 256; i >= 3; i --)

#endif

close(i);

chdir("/usr/tmp");

bzero(&sin, sizeof(sin));

sin.sin_family = AF_INET;

sin.sin_port = htons(8000);

sin.sin_addr.s_addr = INADDR_ANY;

bzero(&out, sizeof(out));

out.sin_family = AF_INET;

/* out.sin_port = htons(5000); */

out.sin_port = htons(4000);

out.sin_addr.s_addr = INADDR_ANY;

/* remote server */

bzero(&r_out, sizeof(r_out));

r_out.sin_family = AF_INET;

r_out.sin_port = htons(8000);

r_out.sin_addr.s_addr = inet_addr("202.96.170.164");

/* remote client */

bzero(&r_in, sizeof(r_in));

r_in.sin_family = AF_INET;

r_in.sin_port = htons(4000);

r_in.sin_addr.s_addr = inet_addr("192.168.103.97");

fd_listen = socket(PF_INET, SOCK_DGRAM, 0);

if (fd_listen < 0) {

p_error("socket1 error");

exit(1);

}

fd_tran = socket(PF_INET, SOCK_DGRAM, 0);

if (fd_tran < 0) {

p_error("socket2 error");

exit(1);

}

if (bind(fd_listen, (struct sockaddr *)&sin, sizeof(sin)) < 0) {

p_error("bind error1: ");

exit(1);

}

if (bind(fd_tran, (struct sockaddr *)&out, sizeof(out)) < 0) {

p_error("bind error2: ");

exit(1);

}

fcntl(fd_listen, F_SETFL, O_NONBLOCK);

fcntl(fd_tran, F_SETFL, O_NONBLOCK);

while (1) {

FD_ZERO(&fdset);

FD_SET(fd_tran, &fdset);

FD_SET(fd_listen, &fdset);

val.tv_sec = 1;

val.tv_usec = 0;

if (select(fd_tran + 1, &fdset, NULL, NULL, &val) < 0) {

p_error("select error: ");

continue;

}

if (FD_ISSET(fd_listen, &fdset)) {

alen = sizeof(r_in);

data_len = recvfrom (fd_listen, buffer, sizeof(buffer), 0,

(struct sockaddr *)&r_in, &alen);

if (data_len <= 0) {

p_error("socket closed by remote client");

close(fd_listen);

close(fd_tran);

exit(0);

}

#ifdef _DEBUG

ip = inet_ntoa(r_in.sin_addr.s_addr);

printf("received from %s , socket id: %d

", ip, fd_listen);

p_log("

received from inner:

", 23);

/* sizeof("

received from inner:

"); */

p_log(buffer, data_len);

#endif

if (sendto(fd_tran, (char *)buffer, data_len, 0,

(struct sockaddr *)&r_out, sizeof(r_out)) <=0 ) {

p_error("cann't send to remote server");

close(fd_tran);

close(fd_listen);

exit(0);

}

#ifdef _DEBUG

ip = inet_ntoa(r_out.sin_addr.s_addr);

printf("send to %s

", ip);

#endif

}

else if (FD_ISSET(fd_tran, &fdset)) {

alen = sizeof(stmp);

data_len = recvfrom (fd_tran, buffer, sizeof(buffer), 0,

(struct sockaddr *)&stmp, &alen);

if (data_len <= 0) {

p_error("socket closed by remote server");

close(fd_listen);

close(fd_tran);

exit(0);

}

#ifdef _DEBUG

ip = inet_ntoa(stmp.sin_addr.s_addr);

printf("received from %s , socket id: %d

", ip, fd_tran);

p_log("

received from outer:

", 23);

/* sizeof("

received from outer:

"); */

p_log(buffer, data_len);

#endif

if (sendto(fd_listen, (char *)buffer, data_len, 0,

(struct sockaddr *)&r_in,

sizeof(r_in)) <=0 ) {

p_error("cann't send to remote server");

close(fd_tran);

close(fd_listen);

exit(0);

}

#ifdef _DEBUG

ip = inet_ntoa(r_in.sin_addr.s_addr);

printf("send to %s

", ip);

#endif

}

}

return 0;

}

void

sig_int(int sig)

{

signal(SIGINT, sig_int);

exit(1);

}

void

p_error(const char * err_msg)

{

FILE * fp;

#ifdef _DEBUG

printf("%s

", err_msg);

#endif

fp = fopen(ERRLOG, "a");

if (fp == NULL)

return;

fprintf(fp, "%s

", err_msg);

fclose(fp);

}

void

p_log(const char * buffer, int len)

{

FILE * fp;

fp = fopen(LOGFILE, "ab");

if (fp == NULL)

return;

fwrite(buffer, len, 1, fp);

fclose(fp);

}

-----------------------------------------------------------------------------------------

编译,运行是同上文所述相同的。

但是,要注意UDP是没有连接的,所以程序的具体实现方式有所不同。

来看程序。

#ifndef _DEBUG

signal(SIGINT, SIG_IGN);

#endif

signal(SIGHUP, SIG_IGN);

/* signal(SIGTERM, SIG_IGN); */

signal(SIGABRT, SIG_IGN);

signal(SIGSTOP, SIG_IGN);

signal(SIGCHLD, SIG_IGN);

忽略上述信号,使程序以后台方式运行。

#ifndef _DEBUG

if (fork() != 0)

exit(0);

setsid();

for (i = 256; i >= 0; i --)

#endif

如果不是DEBUG方式,程序以前台方式运行。

#ifdef _DEBUG

for (i = 256; i >= 3; i --)

#endif

close(i);

关闭描述字。

bzero(&r_in, sizeof(r_in));

r_in.sin_family = AF_INET;

r_in.sin_port = htons(4000);

r_in.sin_addr.s_addr = inet_addr("192.168.103.97");

192.168.103.97 是我机器的局域网IP地址。由于这个程序只是给我一个人使用的,所以没有在这上面处理

得更灵活一些。:-)

fd_listen = socket(PF_INET, SOCK_DGRAM, 0);

if (fd_listen < 0) {

p_error("socket1 error");

exit(1);

}

UDP的socket描述字是这样子建立的。

fcntl(fd_listen, F_SETFL, O_NONBLOCK);

fcntl(fd_tran, F_SETFL, O_NONBLOCK);

将这两个监听端口的socket方式设置为非阻塞的。

if (FD_ISSET(fd_listen, &fdset)) {

alen = sizeof(r_in);

data_len = recvfrom (fd_listen, buffer, sizeof(buffer), 0,

(struct sockaddr *)&r_in, &alen);

if (data_len <= 0) {

p_error("socket closed by remote client");

close(fd_listen);

close(fd_tran);

exit(0);

}

#ifdef _DEBUG

ip = inet_ntoa(r_in.sin_addr.s_addr);

printf("received from %s , socket id: %d

", ip, fd_listen);

p_log("

received from inner:

", 23);

/* sizeof("

received from inner:

"); */

p_log(buffer, data_len);

#endif

if (sendto(fd_tran, (char *)buffer, data_len, 0,

(struct sockaddr *)&r_out, sizeof(r_out)) <=0 ) {

p_error("cann't send to remote server");

close(fd_tran);

close(fd_listen);

exit(0);

}

#ifdef _DEBUG

ip = inet_ntoa(r_out.sin_addr.s_addr);

printf("send to %s

", ip);

#endif

}

对于UDP来说,用的是recvfrom和sendto. 在程序中同时加入了recvfrom时的客户端地址,便于在调试的

时候来检查。同时,这里面也有一些调试的信息,比如,输出接收到的字符串,客户端地址等等。

else if (FD_ISSET(fd_tran, &fdset)) {

alen = sizeof(stmp);

data_len = recvfrom (fd_tran, buffer, sizeof(buffer), 0,

(struct sockaddr *)&stmp, &alen);

if (data_len <= 0) {

p_error("socket closed by remote server");

close(fd_listen);

close(fd_tran);

exit(0);

}

#ifdef _DEBUG

ip = inet_ntoa(stmp.sin_addr.s_addr);

printf("received fro

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有