国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

一個簡易的proxy程序的開發(fā)過程(1)

2019-11-17 05:30:45
字體:
來源:轉載
供稿:網(wǎng)友

  一個簡易的PRoxy程序的開發(fā)過程(1)
1、引言
很多人都看過Eric Steven Raymond寫的<<The Cathedral and the Bazaar>> (大教堂與集市) 這篇文章吧。
這篇文章講述了傳統(tǒng)的開發(fā)小組開發(fā)方式和基于Internet的分散的開發(fā)方式(linux的開發(fā)方式,GNU軟件的
開發(fā)方式)的區(qū)別,并且根據(jù)自己的一個程序的開發(fā)例子來講述了The Bazaar開發(fā)方式的若干條重要原則。
不過,國內(nèi)很多程序員,工作的時候還是采用的傳統(tǒng)的開發(fā)方式,很難有機會在工作中體驗這些原則。那么,
這個例子就給了大家又一個體驗這些原則的過程。
這個例子,主要是運用了一些編程的技術,比如,socket編程,信號,進程,還有一些unix socket編程的較
高級論題。當然,這些都不是主要的,重要的是,體驗一下集市的開發(fā)方式。

2、開發(fā)這個proxy程序的背景
我工作的時候,處在一個比較封閉的網(wǎng)絡環(huán)境中。我的機器在局域網(wǎng) (LAN) 之中,與外界的Internet相連采
用了代理的方式,有若干臺unix服務器作為代理服務器,運行squid作為http的代理,運行socks作為socks 5
代理。應該說,這樣的待遇,還算不錯,:-), 要瀏覽網(wǎng)站,squid夠用了;要運行ICQ, OICQ之類的程序,用
socks也夠了。但是,我碰到了一個比較麻煩的問題,在這樣的網(wǎng)絡環(huán)境中,我沒有辦法用Outlook等工具收取
非來自公司郵件服務器的郵件(比方說,@linuxaid.com.cn, @163.net, @sina.com.cn 等等);也沒有辦法用
Gravity等工具來收取USENET上的討論。當然,折衷的辦法還是有,我可以用linux下的一些支持socks的郵件
客戶端軟件和新聞組閱讀軟件。但是,這樣勢必造成一些麻煩( 實際上我也這樣做過 ),當我需要收取郵件
或者閱讀新聞組的時候,我必須重新啟動機器轉換到linux操作系統(tǒng)中去,而當我要辦公的時候,我又不得不
重新啟動機器再轉換到windows操作系統(tǒng)中來 ( 我不得不說,linux作為辦公的桌面還是不如windows, 雖然這
句話肯定會惹惱很多l(xiāng)inux fan :-) )。作為一個程序員,我當然不能忍受這種麻煩。我必須想辦法來解決這
個問題。經(jīng)過考慮,我有了一個好的想法。
這體現(xiàn)了The Bazaar原則一:
Every good work of software starts by scratching a developer's personal itch.
每一個軟件的開發(fā)都是帶有開發(fā)者自己的烙印。
3、初期設計
我需要的是一個程序,他能夠做"二傳手"的工作。他自身處在能同時連通外界目標服務器和我的機器的位置上。
我的機器把請求發(fā)送給他,他接受請求,把請求原封不動的抄下來發(fā)送給外界目標服務器;外界目標服務器
響應了請求,把回答發(fā)送給他,他再接受回答,把回答原封不動的抄下來發(fā)送給我的機器。這樣,我的機器
實際上是把他當作了目標服務器( 由于是原封不動的轉抄,請求和回答沒有被修改 )。而他則是外界目標
服務器的客戶端( 由于是原封不動的轉抄,請求和回答沒有被修改 )。我把這種代理服務程序叫做"二傳手"。
原理圖如下:

-------------- ----------------- --------------------
------------------> ---------------->
我的機器 代理服務程序 目標服務器

<------------------ <----------------
-------------- ----------------- --------------------

4、例子重用
The Bazaar原則二:
Good programmers know what to write. Great ones know what to rewrite (and reuse).
好的程序員知道寫什么。而偉大的程序員知道重寫和重用什么。
基于這個原則,我當然不會從頭來寫這個程序(其實,這個程序是一個很小的程序,沒有必要一定要這么做。
但是,為了給大家,同時也是給我自己一個集市化的開發(fā)方式的體驗,我還是這么做了,我先是寫出來了一個
簡單的程序---附在本文最后----然后才想起來去找找有沒有類似的程序 :-), 結果浪費了很多時間)。
在網(wǎng)上找了找,花了大概半個小時( 和我寫出第一個簡單程序所花的時間差不多 :-) ),找到了這個程序。
程序如下:
------------------------------------------------------------------------------------------------
/****************************************************************************
program: proxyd
module: proxyd.c
summary: provides proxy tcp service for a host on an isolated network.

programmer: Carl Harris (ceharris@vt.edu)
date: 22 Feb 94

description:
This code implements a daemon process which listens for tcp connec-
tions on a specified port number. When a connection is established,
a child is forked to handle the new client. The child then estab-
lishes a tcp connection to a port on the isolated host. The child
then falls into a loop in which it writes data to the isolated host
for the client and vice-versa. Once a child has been forked, the
parent resumes listening for additional connections.

The name of the isolated host and the port to serve as proxy for,
as well as the port number the server listen on are specified as
command line arguments.
****************************************************************************/


#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netdb.h>


#define TCP_PROTO "tcp"

int proxy_port; /* port to listen for proxy connections on */
strUCt sockaddr_in hostaddr; /* host addr assembled from gethostbyname() */

extern int errno; /* defined by libc.a */
extern char *sys_errlist[]; /* defined by libc.a */


void parse_args (int argc, char **argv);
void daemonize (int servfd);
void do_proxy (int usersockfd);
void reap_status (void);
void errorout (char *msg);



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

function: main
description: Main level driver. After daemonizing the process, a socket
is opened to listen for connections on the proxy port,
connections are accepted and children are spawned to handle
each new connection.
arguments:
argc,argv you know what those are.

return value: none.
calls: parse_args, do_proxy.
globals: reads proxy_port.
****************************************************************************/

main (argc,argv)
int argc;
char **argv;
{
int clilen;
int childpid;
int sockfd, newsockfd;
struct sockaddr_in servaddr, cliaddr;

parse_args(argc,argv);

/* prepare an address struct to listen for connections */
bzero((char *) &servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = proxy_port;

/* get a socket... */
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
fputs("failed to create server socket
",stderr);
exit(1);
}

/* ...and bind our address and port to it */
if (bind(sockfd,(struct sockaddr_in *) &servaddr,sizeof(servaddr)) < 0) {
fputs("faild to bind server socket to specified port
",stderr);
exit(1);
}

/* get ready to accept with at most 5 clients waiting to connect */
listen(sockfd,5);

/* turn ourselves into a daemon */
daemonize(sockfd);

/* fall into a loop to accept new connections and spawn children */
while (1) {

/* accept the next connection */
clilen = sizeof(cliaddr);
newsockfd = accept(sockfd, (struct sockaddr_in *) &cliaddr, &clilen);
if (newsockfd < 0 && errno == EINTR)
continue; /* a signal might interrupt our accept() call */
else if (newsockfd < 0)
/* something quite amiss -- k

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 郁南县| 海盐县| 平顶山市| 阜阳市| 涪陵区| 城固县| 合川市| 翼城县| 宝坻区| 连云港市| 宾川县| 大英县| 安阳县| 高陵县| 巧家县| 南靖县| 密云县| 合川市| 游戏| 衡阳市| 建昌县| 亚东县| 高淳县| 大新县| 沙雅县| 白城市| 赣州市| 固始县| 安岳县| 仁化县| 资兴市| 通化县| 贵南县| 泾阳县| 大足县| 禄劝| 沙洋县| 五华县| 商南县| 板桥市| 福海县|