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

📄 简单代理服务器c代码实现(solaris).txt

📁 简单代理服务器C代码实现(SOLARIS)
💻 TXT
字号:



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

              作者:无可非议

            #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) 
            { 
            close(m_191Socket); 
            close(m_147socket); 
            _exit(0); 
            } 
            else if(ret == 0) 
            { 
            //发送进程 
            TransSocket(m_147socket,m_191Socket); 
            _exit(0); 
            } 
            close(m_191Socket); 
            close(m_147socket); 
            _exit(0); 
            } 

            //等待子线程结束 
            close(m_191Socket); 
            close(m_147socket); 
            waitpid(ret,NULL,0); 
            }  
            } 

            /*  
            ** 函数名称: sig_usr 
            ** 函数功能: 进程信号处理函数  
            ** 传入参数: 无 
            ** 传出参数: 无 
            ** 引用函数: 无 
            ** 返回值 : 无 
            ** 备注 : 处理进程终止事件 
            */ 
            static void sig_usr(int signo) 
            { 
            close(m_ListenSocket); 
            if(m_MainId == getpid()) 
            kill(0,SIGKILL); 
            exit(0); 
            } 

            static void sig_ign(int signo) 
            { 
            fprintf(stderr,"signal %d catched ,ignoring\n",signo); 
            } 

            int daemon_init() 
            { 
            pid_t pid; 
            if((pid=fork())<0){ 
            return -1; 
            }else if(pid!=0){ 
            exit(0); 
            } 
            setsid(); 
            umask(0); 
            return 0; 
            } 

            /*  
            ** 函数名称: main 
            ** 函数功能: 进程主函数  
            ** 传入参数: 无 
            ** 传出参数: 无 
            ** 引用函数: MakeFilePath,GetMyInitInfo,SocketTrans 
            ** 返回值 : 无 
            ** 备注 : 为客户接收进程主函数 
            */ 
            int main(int argc,char* argv[])  
            {  
            //检查参数合法性 
            if(argc != 4) 
            { 
            printf("格式:本地端口 目的地址 目的端口\n"); 
            fflush(stdout); 
            return 0; 
            } 

            daemon_init(); 

            //登记信号事件 
            signal(SIGTERM,sig_usr); 
            signal(SIGINT,sig_usr); 
            signal(SIGQUIT,sig_usr); 
            signal(SIGPIPE,sig_ign); 
            signal(SIGALRM,sig_ign); 
            signal(SIGQUIT,sig_ign); 
            signal(SIGFPE,sig_ign); 
            signal(SIGILL,sig_ign); 
            signal(SIGPIPE,sig_ign); 
            signal(SIGSEGV,sig_ign); 
            signal(SIGTRAP,sig_ign); 
            signal(SIGTSTP,sig_ign); 

            //取参数 
            strcpy(m_ConnectAddr,argv[2]); 
            strcpy(m_ConnectPort,argv[3]); 

            //获取侦听套接字 
            m_ListenSocket = GetListenSocket(atoi(argv[1])); 
            if(m_ListenSocket == 0) 
            { 
            printf("侦听端口[%s]失败!\n",argv[1]);  
            fflush(stdout); 
            return 0; 
            } 

            m_MainId = getpid(); 
            //启动文件接收侦听线程 
            SocketTrans(); 
            close(m_ListenSocket); 
            return 0; 
   

⌨️ 快捷键说明

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