简单代理服务器C代码实现(SOLARIS)

2008-04-09 04:00:28来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

/*
** 编写:无可非议
** 来源:WWW.20CN.NET
** 注意:请注明转贴来源
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/stat.h>

int m_MainId = 0; //主进程ID
int m_ListenSocket = 0; //侦听套接字
char m_ConnectAddr[256] = {0}; //目标地址
char m_ConnectPort[256] = {0}; //目标端口

/*
** 函数名称: GetListenSocket
** 函数功能: 生成侦听套接字
** 传入参数: Port : 侦听端口
** 传出参数: 无
** 引用函数: 无
** 返回值 : 侦听套接字,为0时表示生成套接字失败,其他为套接字句柄
** 备注 : 无
*/
int GetListenSocket(int Port)
{
struct sockaddr_in m_LisAddr = {0};
int m_Socket = 0;
int m_AddrLen = sizeof(struct sockaddr_in);

//配置端口信息
m_LisAddr.sin_family = AF_INET;
m_LisAddr.sin_port = htons(Port);
m_LisAddr.sin_addr.s_addr = INADDR_ANY;

//创建套接字
if ((m_Socket = socket(AF_INET,SOCK_STREAM,0)) < 0 )
{
//创建套接字失败
return 0;
}

//绑定套接字
if(bind(m_Socket, (sockaddr*)&m_LisAddr , m_AddrLen) < 0 )
{
//绑定套接字失败
close(m_Socket);
return 0;
}

//侦听套接字
if(listen(m_Socket,5))
{
//侦听套接字失败
close(m_Socket);
return 0;
}

//侦听套接字生成成功
return m_Socket;
}

/*
** 函数名称: GetConnectSocket
** 函数功能: 生成连接套接字
** 传入参数: pServerAddr : 连接地址 pServerPort : 连接端口
** 传出参数: 无
** 引用函数: 无
** 返回值 : 连接套接字,为0时表示生成套接字失败,其他为套接字句柄
** 备注 : 无
*/
int GetConnectSocket(char* pServerAddr,char* pServerPort)
{
struct sockaddr_in m_ServerAddr = {0};
int m_AddrLen = sizeof(struct sockaddr_in);
int m_Socket = 0;

//初始化连接信息
m_ServerAddr.sin_addr.S_un.S_addr = inet_addr(pServerAddr);
m_ServerAddr.sin_port = htons(atoi(pServerPort));
m_ServerAddr.sin_family = AF_INET;

//创建发送套接字
m_Socket = socket(AF_INET,SOCK_STREAM,0);
if(m_Socket <= 0)
{
//失败
return NULL;
}

//连接客户计算机
if(connect(m_Socket,(sockaddr*)&m_ServerAddr,m_AddrLen) < 0 )
{
close(m_Socket);
return NULL;
}

//连接成功
return m_Socket;
}

/*
** 函数名称: TransSocket
** 函数功能: 完成套接字数据转发
** 传入参数: m_SendSocket : 发送套接字 m_RecvSocket : 接收套接字
** 传出参数: 无
** 引用函数: 无
** 返回值 : 无
** 备注 : 逆反完成全双工
*/
void TransSocket(int m_SendSocket,int m_RecvSocket)
{
char m_Buf[512 * 1024] = {0};
int ret = 0;
fd_set readset;
struct timeval tm = {0};
tm.tv_sec = 3600 * 24;

FD_ZERO(&readset);
FD_SET(m_RecvSocket,&readset);

while(1)
{
if((select(m_RecvSocket 1,&readset,NULL,NULL,&tm)
<= 0))
{
//出错
break;
}
if(!FD_ISSET(m_RecvSocket,&readset)) continue;

ret = recv(m_RecvSocket,m_Buf,512 * 1024 - 1,0);
if(ret < 0)
{
//出错
break;
}
send(m_SendSocket,m_Buf,ret,0);
}
close(m_SendSocket);
close(m_RecvSocket);
}

/*
** 函数名称: SocketTrans
** 函数功能: 工作主函数,完成数据转发,新进程启动
** 传入参数: m_SendSocket : 发送套接字 m_RecvSocket : 接收套接字
** 传出参数: 无
** 引用函数: 无
** 返回值 : 无
** 备注 : 逆反完成全双工
*/
void SocketTrans()
{
struct sockaddr_in m_WorkAddr = {0};
int m_191Socket = 0;
int m_147socket = 0;
int m_WorkAddrLen = 0;

//开始任务执行
while(1)
{
//接受147的连接
m_WorkAddrLen = sizeof(struct sockaddr_in);
m_147socket = accept(m_ListenSocket,
(sockaddr*)&m_WorkAddr , &m_WorkAddrLen);

//检查套接字合法性
if(m_147socket < 0) continue;

//连接191
m_191Socket = GetConnectSocket(m_ConnectAddr,m_ConnectPort);
if(m_191Socket == NULL)
{
close(m_147socket);
continue;
}

int ret = fork();
if(ret < 0)
{
//建立新进程失败
printf("致命错误,无法建立新进程!\n");
fflush(stdout);
close(m_191Socket);
close(m_147socket);
break;
}
else if(ret == 0)
{
//关闭原来端口
close(m_ListenSocket);

//建立二次子进程,防止僵尸进程
ret = fork();
if(ret < 0)
{
close(m_191Socket);
close(m_147socket);
_exit(0);
}
else if(ret == 0)
{
//接收进程
TransSocket(m_191Socket,m_147socket);
_exit(0);
}
ret = fork();
if(ret < 0)
{

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Windows黑客编程基础

下一篇:用VC 实现Windows2000/XP下的休眠