📄 ex_7_1.cpp
字号:
delete (CLIENT_PARAM *)localParam; MyUnlock();#ifdef _WIN32 Sleep(50); _endthread(); return ;#else SysSleep(50); pthread_exit(NULL); return ;#endif}#ifdef _WIN32void ClientProc(void * pParam)#elsevoid * ClientProc(void * pParam)#endif{// 客户端处理线程,把接收的数据发送给目标机器,并把目标机器返回的数据返回到客户端 CLIENT_PARAM * localParam=(CLIENT_PARAM *) pParam; localParam->nEndFlag=0; int nSocket=localParam->nSocket; int nLen=0;#if defined(_WIN32)||defined(_WIN64) MSG msg;#endif int nLoopTotal=0; int nLoopMax=20*300; // 300 秒判断选循环#define nMaxLen 0x1000 char pBuffer[nMaxLen+1]; char pNewBuffer[nMaxLen+1]; memset(pBuffer,0,nMaxLen); memset(pNewBuffer,0,nMaxLen); int nSocketErrorFlag=0; int nNewLen=0; int nNewSocket=CreateSocket(); if(nNewSocket==-1) {// 不能建立套接字,直接返回 CloseSocket(nSocket); EndClient(pParam); } if(ConnectSocket(nNewSocket,GlobalRemoteHost,GlobalRemotePort)<=0) {// 不能建立连接,直接返回 CloseSocket(nSocket); CloseSocket(nNewSocket); EndClient(pParam); } SetSocketNotBlock(nNewSocket); while(!GlobalStopFlag&&!nSocketErrorFlag) { nLoopTotal++;#if defined(_WIN32)||defined(_WIN64) while(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if(GetMessage(&msg,NULL,0,0)!=-1) { TranslateMessage(&msg); DispatchMessage(&msg); } }#endif nLen=SocketRead(nSocket,pBuffer,nMaxLen); // 读取客户端数据 if(nLen>0) { pBuffer[nLen]=0; nLoopTotal=0; nNewLen=SocketWrite(nNewSocket,pBuffer,nLen,30); if(nNewLen<0) // 断开 break; } if(nLen<0) { // 读断开 break; } nNewLen=SocketRead(nNewSocket,pNewBuffer,nMaxLen); // 读取返回数据 if(nNewLen>0) { pNewBuffer[nNewLen]=0;// WriteBaseLog(pNewBuffer); nLoopTotal=0; nLen=SocketWrite(nSocket,pNewBuffer,nNewLen,30); if(nLen<0) // 断开 break; } if(nNewLen<0) { // 读断开 break; } if((nSocketErrorFlag==0)&&(nLoopTotal>0)) { SysSleep(50); if(nLoopTotal>=nLoopMax) { nLoopTotal=0; } } } CloseSocket(nNewSocket); CloseSocket(nSocket); EndClient(pParam);#ifdef _WIN32 Sleep(50); _endthread(); return ;#else SysSleep(50); pthread_exit(NULL); return NULL;#endif}#ifdef _WIN32void AcceptProc(void * pParam)#elsevoid * AcceptProc(void * pParam)#endif{ SERVER_PARAM * localParam=(SERVER_PARAM *) pParam; int s; unsigned int Len; sockaddr_in inAddr; unsigned long nIndex; char pClientName[256]; unsigned int nCurIndex=(unsigned int)-1; unsigned int nIndexOff=0; CLIENT_PARAM * localClientParam=NULL; localParam->nEndFlag=0; for(nIndex=0;nIndex<MAX_SOCKET;nIndex++) { localParam->pClientSocket[nIndex]=-1; } while(!GlobalStopFlag) { Len=sizeof(sockaddr_in); inAddr=localParam->ServerSockaddr;#ifdef Linux s=accept(localParam->nSocket,(sockaddr *)(&inAddr), (socklen_t *)&Len);#else#if defined(_WIN32)||defined(_WIN64) s=(int)accept((SOCKET)localParam->nSocket,(sockaddr *)(&inAddr), (int *)&Len);#else s=accept(localParam->nSocket,(sockaddr *)(&inAddr), (int *)&Len);#endif#endif if(s==0) break; // socket error if(s==-1) { if(CheckSocketError(s)) break; // socket error SysSleep(50); continue; } MyLock(); strcpy(pClientName,inet_ntoa(inAddr.sin_addr));// 在Linux下,inet_ntoa()函数是线程不安全的 MyUnlock(); SetSocketNotBlock(s); nIndexOff=nCurIndex; MyLock();// 查找空闲的套接字位置,// 因为客户端的套接字线程处理程序也要操作此数据,因此需要加锁 for(nIndex=0;nIndex<MAX_SOCKET;nIndex++) { nIndexOff++; nIndexOff%=MAX_SOCKET; if(localParam->pClientSocket[nIndexOff]==-1) {// 此偏移量处存放新建立的套接字 localParam->pClientSocket[nIndexOff]=s; nCurIndex=nIndexOff; break; } } MyUnlock(); if(nIndex>=MAX_SOCKET) {// 没有找到存放套接字的偏移量,太多的连接 CloseSocket(s); SysSleep(50); continue; } localClientParam=new CLIENT_PARAM; localClientParam->nEndFlag=1; localClientParam->nIndexOff=nCurIndex; localClientParam->nSocket=s; localClientParam->pServerParam=localParam; memset(localClientParam->szClientName,0,256); strcpy(localClientParam->szClientName,pClientName); int nThreadErr=0;#if defined(_WIN32)||defined(_WIN64) if(_beginthread(ClientProc,NULL,localClientParam)<=1) nThreadErr=1;#else pthread_t localThreadId; nThreadErr=pthread_create(&localThreadId,NULL, (THREADFUNC)ClientProc,localClientParam); if(nThreadErr==0) pthread_detach(localThreadId);// 释放线程私有数据,不必等待pthread_join();#endif if(nThreadErr) {// 建立线程失败 MyLock(); localParam->pClientSocket[nIndexOff]=-1; MyUnlock(); continue; } } int nUsedSocket=MAX_SOCKET; while(nUsedSocket>0) { nUsedSocket=0; SysSleep(50); MyLock(); for(nIndex=0;nIndex<MAX_SOCKET;nIndex++) { if(localParam->pClientSocket[nIndex]!=-1) { nUsedSocket=1; break; } } MyUnlock(); }#ifdef _WIN32 Sleep(50); localParam->nEndFlag=1; _endthread(); return ;#else SysSleep(50); localParam->nEndFlag=1; pthread_exit(NULL); return NULL;#endif}#if !defined(_WIN32)&&!defined(_WIN64)extern "C" void sig_term(int signo){ if(signo==SIGTERM) { GlobalStopFlag=1; signal(SIGTERM,sig_term); signal(SIGHUP,SIG_IGN); signal(SIGKILL,sig_term); signal(SIGINT,sig_term); signal(SIGPIPE,SIG_IGN); signal(SIGALRM,SIG_IGN); }}long daemon_init(){ pid_t pid; signal(SIGALRM,SIG_IGN); signal(SIGPIPE,SIG_IGN); if((pid=fork())<0) return 0; else if(pid!=0) exit(0); setsid(); signal(SIGTERM,sig_term); signal(SIGINT,sig_term); signal(SIGHUP,SIG_IGN); signal(SIGKILL,sig_term); signal(SIGPIPE,SIG_IGN); signal(SIGALRM,SIG_IGN); fclose(stdin); fclose(stdout); fclose(stderr); return 1;}#elseBOOL WINAPI ControlHandler ( DWORD dwCtrlType ){ switch( dwCtrlType ) { case CTRL_BREAK_EVENT: // use Ctrl+C or Ctrl+Break to simulate case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode case CTRL_CLOSE_EVENT: // close console GlobalStopFlag=1; return TRUE; break; } return FALSE;}#endifint main(int argc, char * argv[]){ if(argc<4) { PrintUsage(argv[0]); return -1; } int nLocalPort=-1; int nRemotePort=-1; nLocalPort=atoi(argv[1]); nRemotePort=atoi(argv[3]); if((nLocalPort<=0)||(nRemotePort<=0)) { printf("invalid local port or remote port \n"); return -1; } char * szRemoteHost=argv[2]; GlobalRemotePort=nRemotePort; strcpy(GlobalRemoteHost,szRemoteHost);#if !defined(_WIN32)&&!defined(_WIN64)// become a daemon program daemon_init();#else InitWinSock(); SetConsoleCtrlHandler( ControlHandler, TRUE );#endif int nSocket=CreateSocket();// create socket if(!CheckSocketValid(nSocket)) { UninitWinSock(); return -1; } int rc=0; rc=BindPort(nSocket,nLocalPort); if(!rc) { CloseSocket(nSocket); UninitWinSock(); return -1; } rc=ListenSocket(nSocket,30); if(!rc) { CloseSocket(nSocket); UninitWinSock(); return -1; } MyInitLock(); SetSocketNotBlock(nSocket); SERVER_PARAM * localServerParam=new SERVER_PARAM; sockaddr_in name; memset(&name,0,sizeof(sockaddr_in)); name.sin_family=AF_INET; name.sin_port=htons((unsigned short)nLocalPort); name.sin_addr.s_addr=INADDR_ANY; localServerParam->ServerSockaddr=name; localServerParam->nSocket=nSocket; localServerParam->nEndFlag=1;#if defined(_WIN32)||defined(_WIN64) uintptr_t localThreadId;#else pthread_t localThreadId;#endif int nThreadErr=0;#if defined(_WIN32)||defined(_WIN64) if((localThreadId=_beginthread(AcceptProc,NULL,localServerParam))<=1) nThreadErr=1;#else nThreadErr=pthread_create(&localThreadId,NULL, (THREADFUNC)AcceptProc,localServerParam); if(nThreadErr==0) pthread_detach(localThreadId);// 释放线程私有数据,不必等待pthread_join();#endif if(nThreadErr) {// 建立线程失败 MyUninitLock(); CloseSocket(nSocket); UninitWinSock(); delete localServerParam; return -1; } while((GlobalStopFlag==0)||(localServerParam->nEndFlag==0)) { SysSleep(500); } MyUninitLock(); CloseSocket(nSocket); UninitWinSock(); delete localServerParam; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -