大虾们帮我看看我的代理服务器程序呀

tujj99 2003-12-17 12:34:22
/*********************************************************************/
/***************WINDOWS SOCKET代理服务器******************************/
/*********************************************************************/
#include <winsock2.h>
#include <stdio.h>
#include <conio.h>

#define MY_SERVER_PORT 5060 /*服务端口 */
#define PROXY_PORT 8080
#define MAX_MSG_SIZE 1023 /*缓冲区的大小 */
#define BACKLOG 5 /*等待服务的最大数*/

SOCKET ser_socket, /* 服务器socket */
cli_socket, /* 客户端SOCKET */
pro_socket; /* 代理服务器socket*/
struct sockaddr_in cli_addr, /* 客户端的地址 */
ser_addr, /* 服务器的地址 */
pro_addr; /* 代理服务器地址*/
char proaddr[]="172.17.1.97";
int addrlen;

/*服务过程;服务器接受一条消息,然后发送一条消息 */
int Server_Proc()
{
int n; /* 接受到的或发送的数据的字节数*/
char msg[MAX_MSG_SIZE+1]; /* 缓冲区*/

/* 接收客户端消息 */
n=recv(cli_socket,msg,MAX_MSG_SIZE,0);
if( n > 0)
{
msg[n]=0;
printf("*********************Receiving from client**************************\n");
// printf("%s\n",msg);
}
else if(n == 0)
{
printf("client connection closed!\n");
getch();
}
else if(n == SOCKET_ERROR)
{
printf("client socket error in recvieving client msg!\n");
getch();
}
/* 初始化代理服务器地址*/
addrlen=sizeof(struct sockaddr_in);
memset(&ser_addr,0,addrlen);
pro_addr.sin_family=AF_INET;
pro_addr.sin_addr.s_addr=inet_addr(proaddr);
pro_addr.sin_port=htons(PROXY_PORT);
//请求连接代理服务器
if(connect(pro_socket,(struct sockaddr *)&pro_addr,addrlen) == SOCKET_ERROR)
{
fprintf(stderr,"Listen Error:%s\n",GetLastError());
getch();
exit(1);
}
else
{
fprintf(stdout,"connect to Proxy(172.17.1.97:8080) successfully!\n");
}
/* 转发消息到代理服务器*/
n = send(pro_socket,msg,sizeof(msg),0);
if( n > 0)
{
printf("***********************Sending to proxy************************\n");
// printf("%s\n",msg);
}
else if(n == 0)
{
printf("\nproxy connection closed!\n");
getch();
}
else if(n == SOCKET_ERROR)
{
printf("proxy socket error in recvieving client msg!\n");
getch();
}

/* 从代理服务器接收消息*/
while(n=recv(pro_socket,msg,MAX_MSG_SIZE,0))
{
msg[n] = '\0';
printf("********************Receiving from proxy**********************\n");
// printf("%s\n",msg);
/* 返回数据给客户端 */
n = send(cli_socket,msg,sizeof(msg),0);
if( n > 0)
{
msg[n] = '\0';
printf("***********************Sending to client**************************\n");
// printf("%s\n",msg);
}
else if(n == 0)
{
printf("proxy connection closed!\n");
getch();
}
else if(n == SOCKET_ERROR)
{
printf("client socket error in recvieving client msg!\n");
getch();
}
}
closesocket(cli_socket);
return 1;
}

void PreExit()
{
WSACleanup();
closesocket(ser_socket);
// closesocket(cli_socket);
closesocket(pro_socket);
}

void main()
{
WSADATA WSAData;
//init WSA
if(WSAStartup(MAKEWORD(2,2),&WSAData))
{
printf("WSA start error!");
exit(0);
}

/*创建连接的SOCKET */
ser_socket = socket(AF_INET,SOCK_STREAM,0);
pro_socket = socket(AF_INET,SOCK_STREAM,0);
if(ser_socket == INVALID_SOCKET
|| pro_socket == INVALID_SOCKET)
{/*创建失败 */
fprintf(stderr,"socker Error:%s\n",GetLastError());
exit(1);
}
else
{
fprintf(stdout,"socket creating successfully!\n");
}

//初始化服务器地址
addrlen=sizeof(struct sockaddr_in);
memset(&ser_addr,0,addrlen);
ser_addr.sin_family=AF_INET;
ser_addr.sin_addr.s_addr=htonl(INADDR_ANY); //任何主机都可以访问
ser_addr.sin_port=htons(MY_SERVER_PORT);
if(bind(ser_socket,(struct sockaddr *)&ser_addr,sizeof(ser_addr)) == SOCKET_ERROR)
{/*绑定失败 */
fprintf(stderr,"Bind Error:%s\n",GetLastError());
PreExit();
exit(1);
}
else
{
fprintf(stdout,"bind socket to 172.17.1.39:5060 successfully!\n");
}

//初始化客户端地址
addrlen = sizeof(struct sockaddr_in);
memset(&pro_addr,0,addrlen);
cli_addr.sin_family=AF_INET;
cli_addr.sin_addr.s_addr=htonl(INADDR_ANY);
cli_addr.sin_port=0;
if(bind(pro_socket,(struct sockaddr *)&cli_addr,sizeof(cli_addr)) == SOCKET_ERROR)
{/*绑定失败 */
fprintf(stderr,"Bind Error:%s\n",GetLastError());
PreExit();
exit(1);
}
else
{
fprintf(stdout,"bind Proxy socket successfully!\n");
}

/*侦听客户端请求*/
if(listen(ser_socket,SOMAXCONN) == SOCKET_ERROR )
{
fprintf(stderr,"Listen Error:%s\n",GetLastError());
PreExit();
exit(1);
}
else
{
fprintf(stdout,"Start listening ....\n");
}

addrlen = sizeof(cli_addr);
while(1)
{
/*等待接收客户连接请求 */
cli_socket = accept(ser_socket,(struct sockaddr*)&cli_addr,&addrlen);
if(cli_socket == INVALID_SOCKET)
{
fprintf(stderr,"Accept Error:%s\n",GetLastError());
}
else
{/*开始服务*/
// CreateThread();
fprintf(stdout,"begin process....\n");
Server_Proc();
}
}
PreExit();
}
...全文
30 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
tujj99 2003-12-19
  • 打赏
  • 举报
回复
/////////////////////
bzero(buf, 1000);
FD_ZERO(&rfd);
FD_SET(fromfd, &rfd);
FD_SET(tofd, &rfd);
select(max + 1, &rfd, NULL, NULL, NULL);
////////////////////

这几句是什么意思啊?解释一下咯
tujj99 2003-12-18
  • 打赏
  • 举报
回复
谢谢 zfive5(醉马Ⅴ) 兄了,代码reading中.......
tujj99 2003-12-17
  • 打赏
  • 举报
回复
才开始学习,所以有很多问题,目前主要是不能完全显示网页的内容,而且速度很慢,还有程序十分不稳定,问题多多呀,help me
醉马不肖 2003-12-17
  • 打赏
  • 举报
回复
http://www.linuxaid.com.cn/articles/4/1/4171082.shtml
醉马不肖 2003-12-17
  • 打赏
  • 举报
回复
一个简单的linux代理示例程序

摘要
这是我写的http代理程序,可以做透明代理或传统代理,使用了3128作为代理端口,并将/proc/sys/net/ipv4/ip_forward置为1(我也不知道为什么),透明代理还要将iptable的端口转发规则加上,现在我也在调试,欢迎大家给提提意见。(2003-12-11 16:39:16)

--------------------------------------------------------------------------------
By twfx


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

void *thread_proc(void *arg)
{
char *p_begin, *p_end;
struct hostent hs1, *hs=&hs1;
struct sockaddr_in soaddrtmp;
char buftmp[50];
int fromfd, tofd;
unsigned char buf[1000];
fd_set rfd;
int number, max=0;
fromfd = *((int *)(arg));
if((number = recv(fromfd, buf, 1000, 0)) == -1) {
close(fromfd);
printf("fromfd=%d is closed now! ", fromfd);
return;
}
bzero(&soaddrtmp, sizeof(struct sockaddr_in));
buf[number]=0;
p_begin = strstr(buf, "Host: ") + 6;
p_end = strchr(p_begin, ' ') - 1;
bzero(buftmp, 50);
strncpy(buftmp, p_begin, p_end - p_begin);
printf("URL========%s", buftmp);
hs = gethostbyname(buftmp);
memcpy(&(soaddrtmp.sin_addr), hs->h_addr, hs->h_length);
printf("ip address=%s ", inet_ntoa(soaddrtmp.sin_addr));
soaddrtmp.sin_port = htons(80);
soaddrtmp.sin_family = AF_INET;
if((tofd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "socket(): sock_to: is error! ");
close(fromfd);
return;
}
if(connect(tofd, (struct sockaddr *)(&soaddrtmp),
sizeof(struct sockaddr)) == -1) {
fprintf(stderr, "connect(): sock_to: %s! ",
strerror(errno));
close(fromfd);
return;
}
send(tofd, buf, number, 0);
if(fromfd < tofd)
max = tofd;
else
max = fromfd;
while(1) {
bzero(buf, 1000);
FD_ZERO(&rfd);
FD_SET(fromfd, &rfd);
FD_SET(tofd, &rfd);
select(max + 1, &rfd, NULL, NULL, NULL);
if(FD_ISSET(fromfd, &rfd)) {
number = recv(fromfd, buf, 1000, 0);
if((number == -1)' '(number == 0)) {
close(fromfd);
printf("fromfd=%d is closed now! ", fromfd);
close(tofd);
return;
}
send(tofd, buf, number, 0);
}
if(FD_ISSET(tofd, &rfd)) {
number = recv(tofd, buf, 1000, 0);
if((number == 0)' '(number == -1)) {
close(tofd);
printf("tofd=%d is closed now! ", tofd);
close(fromfd);
return;
}
send(fromfd, buf, number, 0);
}
}
return;
}

int main()
{
int sock_id;
int id_s;
int length=1;
struct sockaddr_in s_addr;
pthread_t th_id;

if((sock_id = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "socket(): is error! ");
return 1;
}
bzero(&s_addr, sizeof(struct sockaddr_in));
s_addr.sin_port = htons(3128);
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
if(bind(sock_id, (struct sockaddr *)(&s_addr),
sizeof(struct sockaddr)) == -1) {
fprintf(stderr, "bind(): %s! ", strerror(errno));
close(sock_id);
return 1;
}if(listen(sock_id, 200) == -1) { //NOTE: attack of syn
fprintf(stderr, "listen(): %s! ", strerror(errno));
close(sock_id);
return 1;
}

while(1) {
bzero(&s_addr, sizeof(struct sockaddr_in));
if((id_s = accept(sock_id, (struct sockaddr *)(&s_addr),
&length)) == -1) {
fprintf(stderr, "accept(): is error! ");
continue;
}
pthread_create(&th_id, NULL, &thread_proc, &id_s);
// thread_proc((void *)(&id_s));
// doproxy();
//printf("ip=%s port=%d ", inet_ntoa(s_addr.sin_addr), ntohs(s_addr.sin_port));
}
close(sock_id);
return 0;
}

tujj99 2003-12-17
  • 打赏
  • 举报
回复
每个线程接收数据快慢不一,怎么协调?
比如我要从服务器那里得到一个网页index.htm的内容,假设用4个线程,怎么处理?
tujj99 2003-12-17
  • 打赏
  • 举报
回复
grooving(东游西逛) :
是不是每一个线程都使用不同的临时端口去连接服务器?
grooving 2003-12-17
  • 打赏
  • 举报
回复
这个地方一定要创建线程。

{/*开始服务*/
// CreateThread();
fprintf(stdout,"begin process....\n");
Server_Proc();

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧