#include <comlib.h>
int main(int argc, char *argv[])
{
int nListenSock = -1, nLocalSock = -1, nRemoteSock = -1;
pid_t nChild;
if (argc != 2) /* 命令行参数:“proxy1 本地端口” */
{
PrintLog(stdout, "proxy1 LOCALPORT\n");
return 1;
}
/* ---------------------------父进程------------------------------- */
/* ① 创建侦听套接字 */
ASSERT(CreateSock(&nListenSock, atoi(argv[1]), 8) == 0);
PrintLog(stdout, "listen service: service is activated.");
InitServer(); /* ② 进程转后台运行 */
while (1)
{
/* ③ 等待并创建连接套接字 */
if (!VERIFY(AcceptSock(&nLocalSock, nListenSock) == 0))
continue; /* ③ 继续等待 */
VERIFY((nChild = fork()) >= 0); /* ④ 创建子进程 */
if (nChild == 0) break; /* 子进程跳转到子进程代码 */
close(nLocalSock); /* ⑤ 父进程关闭连接套接字 */
}
/* ---------------------------子进程------------------------------- */
close(nListenSock); /* ⑦ 子进程关闭侦听套接字 */
/* 解析HTTP报文头,并与目标服务器建立连接 */
if (HttpConnect(nLocalSock, &nRemoteSock) == 0)
SendReciveServer(nLocalSock, nRemoteSock); /* 通信转发 */
if (nLocalSock >= 0) close(nLocalSock); /* ⑨ 子进程关闭本地端套接字 */
if (nRemoteSock >= 0) close(nRemoteSock);/* ⑨ 子进程关闭目标端套接字 */
}
/* --- 解析HTTP报文头,并与目标服务器建立连接 --- */
int HttpConnect(int nLocalSock, int *nRemoteSock)
{
char szIp[30], buf[4096];
int nread;
memset(buf,0,sizeof(buf));
/* 接收网页浏览端发送的数据请求 */
while ((nread = read(nLocalSock, buf, sizeof(buf))) < 0)
{
if (errno != EINTR) /* 信号导致read中断,继续接收 */
{
perror("read"); /* 其它错,结束子进程 */
return 1;
}
}
memset(szIp, 0, sizeof(szIp));
/* 解析HTTP报文,简单验证报文,并获取目标服务器的IP地址 */
if (GetObjectIp(buf, szIp) != 0) return 2;
/* 连接目标服务器,端口80(网页浏览端口) */
if (!VERIFY(ConnectSock(nRemoteSock, 80, szIp) == 0))
{
PrintLog(stderr, "Connect Server Fail,Addr[%s]", szIp);
return 3; /* 连接目标端失败,结束子进程 */
}
if (WriteFile(*nRemoteSock, buf, nread) != 0) /* 转发数据 */
{
PrintLog(stderr, "Write message to server error[%d]", nread);
perror("write"); /* 数据转发失败,结束子进程 */
return 4;
}
return 0; /* 成功返回 */
}
/* --- 解析HTTP报文,简单验证报文,并获取目标服务器的IP地址 --- */
int GetObjectIp(char *buf, char *ip)
{
char *p = NULL, *p1 = NULL, hostname[50];
struct hostent *host;
if (strstr(buf, "HTTP") == NULL) return 1; /* 验证是否为HTTP报文 */
/* HTTP报文的“Host: ”实体头信息中记载了目标服务器的域名,以下获取域名数据 */
if ((p = strstr(buf, "Host:")) == NULL) return 2; /* HTTP报文错 */
if ((p1 = strstr(p, "\n")) == NULL) return 3; /* HTTP报文错 */
memset(hostname, 0, sizeof(hostname));
strncpy(hostname, p+strlen("Host: "), p1 - p - strlen("Host: "));
/* 去除字符串末端的CRLF(回车换行) */
if (hostname[strlen(hostname) - 1] == '\n' || hostname[strlen(hostname) - 1] == '\r') hostname[strlen(hostname) - 1] = 0;
PrintLog(stderr, "[%s]", hostname);
if ((host = gethostbyname(hostname)) == NULL) /* 域名转协议地址 */
{
herror("gethostbyname");
return 3;
}
strcpy(ip, (char *)inet_ntoa(*((struct in_addr *)host->h_addr)));
PrintLog(stderr, ip);
return 0;
}
int SendReciveServer(int nLocalSock, int nRemoteSock)
{
int nMaxSock;
struct timeval wait;
fd_set fdset;
int ret;
while(1)
{
/* ①创建套接字描述符集合 */
FD_ZERO(&fdset);
FD_SET(nLocalSock,&fdset);
FD_SET(nRemoteSock,&fdset);
/* ②准备超时时间 */
wait.tv_sec=60;
wait.tv_usec=0;
/* ③调用select,检查返回 */
nMaxSock = nLocalSock > nRemoteSock ? nLocalSock : nRemoteSock;
if (select(nMaxSock+1,&fdset, NULL, NULL, &wait) == -1)
{
PrintLog(stderr, "Select Failed.");
return 1;
}
/* ④监测状态变化的套接字 */
/* 如果套接字nLocalSock可以接收,则接收数据,发送数据到套接字nRemoteSock */
if (FD_ISSET(nLocalSock, &fdset))
{
PrintLog(stderr, "Local To Remote");
ret = TransSock(nLocalSock, nRemoteSock);
}
/* 如果套接字nRemoteSock可以接收,则接收数据,发送到套接字nLocalSock */
else if (FD_ISSET(nRemoteSock, &fdset))
{
PrintLog(stderr, "Remote To Local");
ret = TransSock(nRemoteSock, nLocalSock);
}
/* 结果判断 */
if (ret == 1) return 1;
else if (ret == 2) break;
}/* end for while */
return 0;
}
int TransSock(int nReadSock, int nWriteSock)
{
int nread;
char buf[4096];
memset(buf,0,sizeof(buf));
if ((nread = read(nReadSock, buf, sizeof(buf))) < 0) /* 接收数据 */
{
if (errno != EINTR) return 1;
else return 0;
}
else if (nread == 0) /* 套接字关闭 */
{
PrintLog(stderr, "client is close");
return 2;
}
PrintLog(stderr, "[%d]", nread);
if (WriteFile(nWriteSock, buf, nread) != 0) /* 转发数据 */
{
PrintLog(stderr, "Write message to server error[%d]", nread);
perror("write");
return 1;
}
return 0;
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
精通linux下C语言源代码 (184个子文件)
1 62B
makefile.aix 610B
makefile.aix 400B
makedll.aix 328B
makefile.aix 274B
proxy2.c 5KB
htservice2.c 4KB
login1.c 4KB
htservice1.c 4KB
monitor1.c 4KB
monitor3.c 3KB
proxy3.c 3KB
debug.c 3KB
monitor2.c 3KB
htservice.c 3KB
file.c 3KB
tcp.c 3KB
proxy1.c 3KB
shm.c 2KB
msg.c 2KB
trans1.c 2KB
str.c 2KB
lock1.c 2KB
ipcmsg.c 2KB
ipcshm.c 2KB
ls1.c 2KB
config.c 2KB
term3.c 2KB
term3.c 2KB
term2.c 2KB
term2.c 2KB
tcpopt.c 2KB
udp.c 2KB
ipcsem.c 1KB
filesys2sco.c 1KB
filesys2.c 1KB
pipe2.c 1KB
time2.c 1KB
sem.c 1KB
http2.c 1KB
process1.c 1KB
time1.c 1KB
http3.c 1KB
time.c 1KB
process2.c 1KB
tcpto2.c 1KB
str1.c 1KB
str2.c 1018B
filesys1sco.c 1003B
str1.c 984B
filesys1.c 984B
http5.c 962B
shm1.c 936B
init2.c 936B
copynameid.c 921B
tcpto1.c 917B
sema.c 900B
str2.c 899B
semb.c 898B
shm2.c 864B
msg1.c 860B
wshm.c 833B
http1.c 830B
rshm.c 825B
msg1.c 814B
msg2.c 794B
msg2.c 777B
trans1.c 753B
http6.c 724B
open.c 705B
tds.c 696B
seek.c 692B
tcp1.c 669B
wait2.c 631B
pipe1.c 614B
opendll.c 598B
copyname.c 596B
print1.c 581B
pid.c 574B
c1.c 555B
time4.c 547B
time2.c 536B
tcp2.c 529B
timeout2.c 523B
file1.c 519B
file1sco.c 513B
fifo1.c 505B
con1.c 504B
con1.c 504B
file1.c 495B
fork1.c 493B
sig3.c 491B
wdata.c 489B
pipe3.c 475B
rdata.c 468B
b.c 453B
transip1.c 437B
file2.c 422B
timeout3.c 415B
transip.c 411B
共 184 条
- 1
- 2
资源评论
鸡蛋比南瓜大
- 粉丝: 2
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于matlab实现夜间车牌识别程序(1).rar
- 基于matlab实现无线传感器网络无需测距定位算法matlab源代码 包括apit,dv-hop,amorphous在内的共7个
- 基于python的yolov5实现的旋转目标检测
- 基于matlab实现无线传感器网络 CAB定位仿真程序 这是无线传感器节点定位CAB算法的仿真程序,由matlab完成.rar
- 基于matlab实现图像处理,本程序使用背景差分法对来往车辆进行检测和跟踪.rar
- 基于matlab实现视频监控中车型识别代码,自己写的,希望和大家多多交流.rar
- springcodespringcodespringcodespringcode
- 基于matlab实现权值的MAXDEV无线传感器网络定位算法研究 MAXDEV 无线传感器 定位 算法.rar
- sdk.config
- 基于matlab实现配电网三相潮流计算方法,对几种常用的配电网潮流计算方法进行了对比分析.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功