用delphi开发代理服务器(100分)

  • 主题发起人 主题发起人 zoulin
  • 开始时间 开始时间
Z

zoulin

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大侠
在拨号上网中,为了能够使用局域网中电脑通过nt连接到internet需要代理服务器,
如何开发代理服务器,请大家畅所欲言!
 
代码己发请查收。
 
我也想要
 
我也想要!
 
今年电脑报29,30,31期编程学堂有用Delphi设计代理服务器的文章,还有源码,你去找找吧.
 
wuwo
电脑报29,30,31期上的资料我仔细读过,但是有问题,代码所实现的功能并不象说的那么
管用!我手边一时又没有关于TServerSocket,TClientScoket的资料,故希望能够在网上向
大家学习。

悲酥清风
您发的代码我没有收到,麻烦您重发一次。thank you!
my email:liyigang@263.net
 
抱歉,我说的就是《电脑报》上的。
不过,好像没问题啊。
 
给我也发一份吧!悲酥清风
abug@yeah.net

小弟现在刚开始做网络,对
于代理还不是很清楚机理,
有空的话那位大虾给讲讲 :)
 
悲酥清风,代理服务器源代码,来一份,谢谢。
xbeta@163.net
 
我最近也在考虑这个,有空多交流。
 
你在大富翁里检索一下
 
各位,不好意思,比较忙,需要的将在下午发货。
 
悲酥清风,请也给我一份,谢谢。
 
请给我一份,谢谢悲酥清风。
 
悲酥清风:

我也想要一份,能否给我发一份,delphiasp@263.net
 
各位:
我现在在网上将代码贴出共大家参考。(里面使用了rxlib2.75中的控件)
如果您在该代码中受到了启发,请与大家共享。
unit main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Menus, ScktComp, RXShell, RxMenus, AppEvent, Mask,
ToolEdit, CurrEdit;

type
MySe_record=record
Used:boolean;
SS_handle:integer;
Csocket:tclientsocket;
lookingup:boolean;
lookuptime:integer;
request:boolean;
request_str:string;
client_connected:boolean;
remote_connected:boolean;
end;
type
TForm1 = class(TForm)
ClientSocket1: TClientSocket;
ServerSocket1: TServerSocket;
Panel1: TPanel;
Memo1: TMemo;
Label1: TLabel;
PopupMenu1: TRxPopupMenu;
N11: TMenuItem;
N21: TMenuItem;
N01: TMenuItem;
mhssoft: TMenuItem;
AppEvents: TAppEvents;
TrayIcon1: TRxTrayIcon;
N1: TMenuItem;
N2: TMenuItem;
Edit1: TCurrencyEdit;
Label2: TLabel;
Edit2: TEdit;
Label3: TLabel;
Edit3: TCurrencyEdit;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Write(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
public
service_enabled:boolean;
MySe:array of MySe_record;
MySes:integer;
lookuptimeout:integer;
invalidrequests:integer;
{ Public declarations }
end;

var
Form1: TForm1;
var
tmp:string;

implementation

{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
caption:=application.Title;
// edit2.Text:=MacData20001.Local_IP;
edit2.ReadOnly:=true;
memo1.Align:=alclient;
serversocket1.port:=round(edit3.value);
serversocket1.Active:=true;
application.Minimize;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if service_enabled then
serversocket1.Active:=false;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
line,host:string;
i,j,port:integer;
begin
tmp:=socket.ReceiveText;
memo1.ReadOnly:=false;
memo1.Lines.Add(tmp);
memo1.ReadOnly:=true;
j:=pos(chr(13)+chr(10),tmp);
while j>0 do begin
line:=copy(tmp,1,j-1);
delete(tmp,1,j+1);
j:=pos('Host',line);
if j>0 then begin
delete(line,1,j+5);
j:=pos(':',line);
if j>0 then begin
host:=copy(line,1,j-1);
delete(line,1,j);
try
port:=strtoint(line);
except
port:=80;
end;
end else begin
host:=trim(line);
port:=80;
end;
if not clientsocket1.active then begin
clientsocket1.host:=host;
clientsocket1.port:=port;
clientsocket1.active:=true;
end else clientsocket1.socket.sendtext(tmp);
break;
end;
j:=pos(#13+#10,tmp);
end;
end;

procedure TForm1.ClientSocket1Write(Sender: TObject;
Socket: TCustomWinSocket);
begin
socket.SendText(tmp);
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
i,j:integer;
rec_bytes:integer;
rec_buffer:array[0..2047] of char;
begin
rec_bytes:=socket.ReceiveBuf(rec_buffer,2048);
serversocket1.Socket.Connections[j-1].SendBuf(rec_buffer,rec_bytes);
end;
end.
 
各位:
我现在在网上将代码贴出共大家参考。(里面使用了rxlib2.75中的控件)
如果您在该代码中受到了启发,请与大家共享。
unit main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Menus, ScktComp, RXShell, RxMenus, AppEvent, Mask,
ToolEdit, CurrEdit;

type
MySe_record=record
Used:boolean;
SS_handle:integer;
Csocket:tclientsocket;
lookingup:boolean;
lookuptime:integer;
request:boolean;
request_str:string;
client_connected:boolean;
remote_connected:boolean;
end;
type
TForm1 = class(TForm)
ClientSocket1: TClientSocket;
ServerSocket1: TServerSocket;
Panel1: TPanel;
Memo1: TMemo;
Label1: TLabel;
PopupMenu1: TRxPopupMenu;
N11: TMenuItem;
N21: TMenuItem;
N01: TMenuItem;
mhssoft: TMenuItem;
AppEvents: TAppEvents;
TrayIcon1: TRxTrayIcon;
N1: TMenuItem;
N2: TMenuItem;
Edit1: TCurrencyEdit;
Label2: TLabel;
Edit2: TEdit;
Label3: TLabel;
Edit3: TCurrencyEdit;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Write(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
public
service_enabled:boolean;
MySe:array of MySe_record;
MySes:integer;
lookuptimeout:integer;
invalidrequests:integer;
{ Public declarations }
end;

var
Form1: TForm1;
var
tmp:string;

implementation

{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
caption:=application.Title;
// edit2.Text:=MacData20001.Local_IP;
edit2.ReadOnly:=true;
memo1.Align:=alclient;
serversocket1.port:=round(edit3.value);
serversocket1.Active:=true;
application.Minimize;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if service_enabled then
serversocket1.Active:=false;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
line,host:string;
i,j,port:integer;
begin
tmp:=socket.ReceiveText;
memo1.ReadOnly:=false;
memo1.Lines.Add(tmp);
memo1.ReadOnly:=true;
j:=pos(chr(13)+chr(10),tmp);
while j>0 do begin
line:=copy(tmp,1,j-1);
delete(tmp,1,j+1);
j:=pos('Host',line);
if j>0 then begin
delete(line,1,j+5);
j:=pos(':',line);
if j>0 then begin
host:=copy(line,1,j-1);
delete(line,1,j);
try
port:=strtoint(line);
except
port:=80;
end;
end else begin
host:=trim(line);
port:=80;
end;
if not clientsocket1.active then begin
clientsocket1.host:=host;
clientsocket1.port:=port;
clientsocket1.active:=true;
end else clientsocket1.socket.sendtext(tmp);
break;
end;
j:=pos(#13+#10,tmp);
end;
end;

procedure TForm1.ClientSocket1Write(Sender: TObject;
Socket: TCustomWinSocket);
begin
socket.SendText(tmp);
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
i,j:integer;
rec_bytes:integer;
rec_buffer:array[0..2047] of char;
begin
rec_bytes:=socket.ReceiveBuf(rec_buffer,2048);
serversocket1.Socket.Connections[j-1].SendBuf(rec_buffer,rec_bytes);
end;
end.
 
我来贴一个,但是unix下用c的,不过很有参考价值,大家可以参考一下.

发信人: stwzyang (hook), 信区: Winsock
标 题: Proxy source code
发信站: BBS 水木清华站 (Sat Jan 3 04:14:04 1998)


/****************************************************************************
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/r/n",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/r/n",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 -- kill the server */
errorout("failed to accept connection");

/* fork a child to handle this connection */
if ((childpid = fork()) == 0) {
close(sockfd);
do_proxy(newsockfd);
exit(0);
}

/* if fork() failed, the connection is silently dropped -- oops! */

close(newsockfd);
}
}



/****************************************************************************
function: parse_args
description: parse the command line args.
arguments:
argc,argv you know what these are.

return value: none.
calls: none.
globals: writes proxy_port, writes hostaddr.
****************************************************************************/

void parse_args (argc,argv)
int argc;
char **argv;
{
int i;
struct hostent *hostp;
struct servent *servp;
unsigned long inaddr;
struct {
char proxy_port [16];
char isolated_host [64];
char service_name [32];
} pargs;


if (argc < 4) {
printf("usage: %s <proxy-port> <host> <service-name|port-number>/r/n",
argv[0]);
exit(1);
}

strcpy(pargs.proxy_port,argv[1]);
strcpy(pargs.isolated_host,argv[2]);
strcpy(pargs.service_name,argv[3]);

for (i = 0; i < strlen(pargs.proxy_port); i++)
if (!isdigit(*(pargs.proxy_port + i)))
break;

if (i == strlen(pargs.proxy_port))
proxy_port = htons(atoi(pargs.proxy_port));
else {
printf("%s: invalid proxy port/r/n",pargs.proxy_port);
exit(0);
}

bzero(&hostaddr,sizeof(hostaddr));
hostaddr.sin_family = AF_INET;
if ((inaddr = inet_addr(pargs.isolated_host)) != INADDR_NONE)
bcopy(&inaddr,&hostaddr.sin_addr,sizeof(inaddr));
else if ((hostp = gethostbyname(pargs.isolated_host)) != NULL)
bcopy(hostp->h_addr,&hostaddr.sin_addr,hostp->h_length);
else {
printf("%s: unknown host/r/n",pargs.isolated_host);
exit(1);
}

if ((servp = getservbyname(pargs.service_name,TCP_PROTO)) != NULL)
hostaddr.sin_port = servp->s_port;
else if (atoi(pargs.service_name) > 0)
hostaddr.sin_port = htons(atoi(pargs.service_name));
else {
printf("%s: invalid/unknown service name or port number/r/n",
pargs.service_name);
exit(1);
}
}



/****************************************************************************
function: daemonize
description: detach the server process from the current context,
creating a pristine, predictable environment in which it
will execute.
arguments:
servfd file descriptor in use by server.

return value: none.
calls: none.
globals: none.
****************************************************************************/

void daemonize (servfd)
int servfd;
{
int childpid, fd, fdtablesize;

/* ignore terminal I/O, stop signals */
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGTSTP,SIG_IGN);

/* fork to put us in the background (whether or not the user
specified '&' on the command line */

if ((childpid = fork()) < 0) {
fputs("failed to fork first child/r/n",stderr);
exit(1);
}
else if (childpid > 0)
exit(0); /* terminate parent, continue in child */

/* dissociate from process group */
if (setpgrp(0,getpid()) < 0) {
fputs("failed to become process group leader/r/n",stderr);
exit(1);
}

/* lose controlling terminal */
if ((fd = open("/dev/tty",O_RDWR)) >= 0) {
ioctl(fd,TIOCNOTTY,NULL);
close(fd);
}

/* close any open file descriptors */
for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++)
if (fd != servfd)
close(fd);

/* set working directory to / to allow filesystems to be unmounted */
chdir("/");

/* clear the inherited umask */
umask(0);

/* setup zombie prevention */
signal(SIGCLD,reap_status);

}



/****************************************************************************
function: do_proxy
description: does the actual work of virtually connecting a client to
the telnet service on the isolated host.
arguments:
usersockfd socket to which the client is connected.

return value: none.
calls: none.
globals: reads hostaddr.
****************************************************************************/

void do_proxy (usersockfd)
int usersockfd;
{
int isosockfd;
fd_set rdfdset;
int connstat;
int iolen;
char buf [2048];

/* open a socket to connect to the isolated host */
if ((isosockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
errorout("failed to create socket to host");

/* attempt a connection */
connstat = connect(isosockfd,
(struct sockaddr *) &hostaddr,
sizeof(hostaddr));
switch (connstat) {
case 0:
break;
case ETIMEDOUT:
case ECONNREFUSED:
case ENETUNREACH:
strcpy(buf,sys_errlist[errno]);
strcat(buf,"/r/n");
write(usersockfd,buf,strlen(buf));
close(usersockfd);
exit(1); /* die peacefully if we can't establish a connection */
break;
default:
errorout("failed to connect to host");
}


/* now we're connected, serve fall into the data echo loop */
while (1) {
/* Select for readability on either of our two sockets */
FD_ZERO(&rdfdset);
FD_SET(usersockfd,&rdfdset);
FD_SET(isosockfd,&rdfdset);
if (select(FD_SETSIZE,&rdfdset,NULL,NULL,NULL) < 0)
errorout("select failed");

/* is the client sending data? */
if (FD_ISSET(usersockfd,&rdfdset)) {
if ((iolen = read(usersockfd,buf,sizeof(buf))) <= 0)
break; /* zero length means the client disconnected */

write(isosockfd,buf,iolen); /* copy to host -- blocking semantics */
}

/* is the host sending data? */
if (FD_ISSET(isosockfd,&rdfdset)) {
if ((iolen = read(isosockfd,buf,sizeof(buf))) <= 0)
break; /* zero length means the host disconnected */

write(usersockfd,buf,iolen); /* copy to client -- blocking semantics */
}
}

/* we're done with the sockets */
close(isosockfd);
close(usersockfd);
}



/****************************************************************************
function: errorout
description: displays an error message on the console and kills the
current process.
arguments:
msg message to be displayed.

return value: none -- does not return.
calls: none.
globals: none.
****************************************************************************/

void errorout (msg)
char *msg;
{
FILE *console;

console = fopen("/dev/console","a");
fprintf(console,"proxyd: %s/r/n",msg);
fclose(console);
exit(1);
}



/****************************************************************************
function: reap_status
description: handle a SIGCLD signal by reaping the exit status of the
perished child, and discarding it.
arguments: none.
return value: none.
calls: none.
globals: none.
****************************************************************************/

void reap_status ()
{
int pid;
union wait status;

while ((pid = wait3(&status,WNOHANG,NULL)) > 0)
; /* loop while there are more dead children */
}


--
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.193.65.100]
发信人: stwzyang (hook), 信区: Winsock
标 题: About Proxy source code (转帖)
发信站: BBS 水木清华站 (Sat Jan 3 04:19:25 1998)

偶在网上得此proxyd,先post出来,再慢慢研究。。。

17 Dev 1997

Author: Carl Harris (ceharris@vt.edu)
Compiler: TjL <luomat@peak.org>

Compiled by:
cc -O2 -object -s /
-arch m68k -arch i386 -arch hppa -arch sparc /
proxyd.c -o proxyd


This is a little daemon I felt was useful and was able to compile, so I thought I would make it available.

I did not write this! I am just compiling and distributing. The source code hadd no restrictions on doing so.

All I know as far as how to use it is what it says:

usage: proxyd <proxy-port> <host> <service-name|port-number>

Which means:

proxyd localport-on-this-machine the-host-this-is-to port-or-name

EXAMPLE:

Say you have a machine named MYHOST want to bind your port #777 to the TELNET poort of the host REMOTEHOST.

Use: proxyd 777 REMOTEHOST telnet

Then if you did 'telnet MYHOST 777' you would actually connect to the TELNET porrt of the host REMOTEHOST.

As far as the 'service-name/port-number' goes: services can be referred to eitheer by a number or a name. For example, NNTP requests are usually on port 119, so if you wanted to connect directly to a machine to do NNTP you could do either:

telnet REMOTEHOST nntp
or
telnet REMOTEHOST 119


NOTE/WARNING: Make sure to use an unused port on your machine! If you are not ssure, do this:

Use: proxyd 777 REMOTEHOST telnet

Then if you did 'telnet MYHOST 777' you would actually connect to the TELNET por

As far as the 'service-name/port-number' goes: services can be referred to eithe

telnet REMOTEHOST nntp
or
telnet REMOTEHOST 119


NOTE/WARNING: Make sure to use an unused port on your machine! If you are not srt of the host REMOTEHOST.

nidump services .

to see a listing of all the services known on your machine.

This program does NOT always have to be run as root... Some ports are available even to regular users, it appears.



--

 
多人接受答案了。
 
后退
顶部