⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxy2.c

📁 本文件介绍了unix内核的c源代码
💻 C
字号:
#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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -