?? 簡單代理服務器c代碼實現(xiàn)(solaris).txt
字號:
簡單代理服務器C代碼實現(xiàn)(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}; //目標端口
/*
** 函數(shù)名稱: GetListenSocket
** 函數(shù)功能: 生成偵聽套接字
** 傳入?yún)?shù): Port : 偵聽端口
** 傳出參數(shù): 無
** 引用函數(shù): 無
** 返回值 : 偵聽套接字,為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;
//創(chuàng)建套接字
if ((m_Socket = socket(AF_INET,SOCK_STREAM,0)) < 0 )
{
//創(chuàng)建套接字失敗
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;
}
/*
** 函數(shù)名稱: GetConnectSocket
** 函數(shù)功能: 生成連接套接字
** 傳入?yún)?shù): pServerAddr : 連接地址 pServerPort : 連接端口
** 傳出參數(shù): 無
** 引用函數(shù): 無
** 返回值 : 連接套接字,為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;
//創(chuàng)建發(fā)送套接字
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;
}
/*
** 函數(shù)名稱: TransSocket
** 函數(shù)功能: 完成套接字數(shù)據(jù)轉(zhuǎn)發(fā)
** 傳入?yún)?shù): m_SendSocket : 發(fā)送套接字 m_RecvSocket : 接收套接字
** 傳出參數(shù): 無
** 引用函數(shù): 無
** 返回值 : 無
** 備注 : 逆反完成全雙工
*/
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);
}
/*
** 函數(shù)名稱: SocketTrans
** 函數(shù)功能: 工作主函數(shù),完成數(shù)據(jù)轉(zhuǎn)發(fā),新進程啟動
** 傳入?yún)?shù): m_SendSocket : 發(fā)送套接字 m_RecvSocket : 接收套接字
** 傳出參數(shù): 無
** 引用函數(shù): 無
** 返回值 : 無
** 備注 : 逆反完成全雙工
*/
void SocketTrans()
{
struct sockaddr_in m_WorkAddr = {0};
int m_191Socket = 0;
int m_147socket = 0;
int m_WorkAddrLen = 0;
//開始任務執(zhí)行
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)
{
//關(guān)閉原來端口
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)
{
//發(fā)送進程
TransSocket(m_147socket,m_191Socket);
_exit(0);
}
close(m_191Socket);
close(m_147socket);
_exit(0);
}
//等待子線程結(jié)束
close(m_191Socket);
close(m_147socket);
waitpid(ret,NULL,0);
}
}
/*
** 函數(shù)名稱: sig_usr
** 函數(shù)功能: 進程信號處理函數(shù)
** 傳入?yún)?shù): 無
** 傳出參數(shù): 無
** 引用函數(shù): 無
** 返回值 : 無
** 備注 : 處理進程終止事件
*/
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;
}
/*
** 函數(shù)名稱: main
** 函數(shù)功能: 進程主函數(shù)
** 傳入?yún)?shù): 無
** 傳出參數(shù): 無
** 引用函數(shù): MakeFilePath,GetMyInitInfo,SocketTrans
** 返回值 : 無
** 備注 : 為客戶接收進程主函數(shù)
*/
int main(int argc,char* argv[])
{
//檢查參數(shù)合法性
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);
//取參數(shù)
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 + -