📄 ex_7_1.cpp
字号:
// ex_7_1.cpp : Defines the entry point for the console application.// map local port to remote host port#if defined(_WIN32)||defined(_WIN64)#pragma warning(disable: 4996)#include <winsock2.h>#include <windows.h>#include <process.h>#pragma comment(lib,"ws2_32.lib") // 64位环境下需要做相应的调整WORD wVersionRequested;WSADATA wsaData;void InitWinSock(){ wVersionRequested = MAKEWORD( 2, 0 ); WSAStartup(wVersionRequested,&wsaData);}#else#include <pthread.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <netdb.h>#include <arpa/inet.h>#include <unistd.h>#include <signal.h>#include <errno.h>#endif#include "sys/types.h"#include "string.h"#include <sys/types.h>#include <fcntl.h>#include "stdio.h"#include "stdlib.h"extern "C"{typedef void*(*THREADFUNC)(void*);}#if defined(_WIN32)||defined(_WIN64) CRITICAL_SECTION MyMutex;#else pthread_mutex_t MyMutex;#endifint GlobalStopFlag=0;#define MAX_SOCKET 0x2000// max client per server#define MAX_HOST_DATA 4096int GlobalRemotePort=-1;char GlobalRemoteHost[256];typedef struct _SERVER_PARAM{ int nSocket; sockaddr_in ServerSockaddr; int nEndFlag; // 判断accept 线程是否结束 int pClientSocket[MAX_SOCKET]; // 存放客户端连接的套接字} SERVER_PARAM;typedef struct _CLIENT_PARAM{ int nSocket; unsigned int nIndexOff; int nEndFlag; // 判断处理客户端连接的线程是否结束 SERVER_PARAM * pServerParam; char szClientName[256];} CLIENT_PARAM;void UninitWinSock(){#if defined(_WIN32)||defined(_WIN64) WSACleanup();#endif}void MyInitLock(){#if defined(_WIN32)||defined(_WIN64) InitializeCriticalSection(&MyMutex);#else pthread_mutex_init(&MyMutex,NULL);#endif}void MyUninitLock(){#if defined(_WIN32)||defined(_WIN64) DeleteCriticalSection(&MyMutex);#else pthread_mutex_destroy(&MyMutex);#endif}void MyLock(){#if defined(_WIN32)||defined(_WIN64) EnterCriticalSection(&MyMutex);#else pthread_mutex_lock(&MyMutex);#endif}void MyUnlock(){#if defined(_WIN32)||defined(_WIN64) LeaveCriticalSection(&MyMutex);#else pthread_mutex_unlock(&MyMutex);#endif}void PrintUsage(const char * szAppName){ printf("Usage : %s <LocalPort> <RemoteHostName> <RemotePort> \n",szAppName);}int CreateSocket(){ int nSocket; nSocket=(int)socket(PF_INET,SOCK_STREAM,0); return nSocket;}int CheckSocketResult(int nResult){// check result;#if !defined(_WIN32)&&!defined(_WIN64) if(nResult==-1) return 0; else return 1;#else if(nResult==SOCKET_ERROR) return 0; else return 1;#endif}int CheckSocketValid(int nSocket){// check socket valid#if !defined(_WIN32)&&!defined(_WIN64) if(nSocket==-1) return 0; else return 1;#else if(((SOCKET)nSocket)==INVALID_SOCKET) return 0; else return 1;#endif}int BindPort(int nSocket,int nPort){ int rc; int optval=1;#if defined(_WIN32)||defined(_WIN64) rc=setsockopt((SOCKET)nSocket,SOL_SOCKET,SO_REUSEADDR, (const char *)&optval, sizeof(int));#else rc=setsockopt(nSocket,SOL_SOCKET,SO_REUSEADDR, (const char *)&optval,sizeof(int));#endif if(!CheckSocketResult(rc)) return 0; sockaddr_in name; memset(&name,0,sizeof(sockaddr_in)); name.sin_family=AF_INET; name.sin_port=htons((unsigned short)nPort); name.sin_addr.s_addr=INADDR_ANY;#if defined(_WIN32)||defined(_WIN64) rc=bind((SOCKET)nSocket,(sockaddr *)&name,sizeof(sockaddr_in));#else rc=bind(nSocket,(sockaddr *)&name,sizeof(sockaddr_in));#endif if(!CheckSocketResult(rc)) return 0; return 1;}int ConnectSocket(int nSocket,const char * szHost,int nPort){ hostent *pHost=NULL;#if defined(_WIN32)||defined(_WIN64) pHost=gethostbyname(szHost); if(pHost==0) { return 0; }#else hostent localHost; char pHostData[MAX_HOST_DATA]; int h_errorno=0;#ifdef Linux int h_rc=gethostbyname_r(szHost,&localHost,pHostData,MAX_HOST_DATA,&pHost,&h_errorno); if((pHost==0)||(h_rc!=0)) { return 0; }#else// we assume defined SunOS pHost=gethostbyname_r(szHost,&localHost,pHostData,MAX_HOST_DATA,&h_errorno); if((pHost==0)) { return 0; }#endif#endif struct in_addr in; memcpy(&in.s_addr, pHost->h_addr_list[0],sizeof (in.s_addr)); sockaddr_in name; memset(&name,0,sizeof(sockaddr_in)); name.sin_family=AF_INET; name.sin_port=htons((unsigned short)nPort); name.sin_addr.s_addr=in.s_addr;#if defined(_WIN32)||defined(_WIN64) int rc=connect((SOCKET)nSocket,(sockaddr *)&name,sizeof(sockaddr_in));#else int rc=connect(nSocket,(sockaddr *)&name,sizeof(sockaddr_in));#endif if(rc>=0) return 1; return 0;}int CloseSocket(int nSocket){ int rc=0; if(!CheckSocketValid(nSocket)) { return rc; }#if defined(_WIN32)||defined(_WIN64) shutdown((SOCKET)nSocket,SD_BOTH); closesocket((SOCKET)nSocket);#else shutdown(nSocket,SHUT_RDWR); close(nSocket);#endif rc=1; return rc;} int ListenSocket(int nSocket,int nMaxQueue){ int rc=0;#if defined(_WIN32)||defined(_WIN64) rc=listen((SOCKET)nSocket,nMaxQueue);#else rc=listen(nSocket,nMaxQueue);#endif return CheckSocketResult(rc);}void SetSocketNotBlock(int nSocket){// 改变文件句柄为非阻塞模式#if defined(_WIN32)||defined(_WIN64) ULONG optval2=1; ioctlsocket((SOCKET)nSocket,FIONBIO,&optval2);#else long fileattr; fileattr=fcntl(nSocket,F_GETFL); fcntl(nSocket,F_SETFL,fileattr|O_NDELAY);#endif}void SysSleep(long nTime)// 延时nTime毫秒,毫秒是千分之一秒{#if defined(_WIN32 )||defined(_WIN64)// windows 代码 MSG msg; while(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if(GetMessage(&msg,NULL,0,0)!=-1) { TranslateMessage(&msg); DispatchMessage(&msg); } } Sleep(nTime);#else// unix/linux代码 timespec localTimeSpec; timespec localLeftSpec; localTimeSpec.tv_sec=nTime/1000; localTimeSpec.tv_nsec=(nTime%1000)*1000000; nanosleep(&localTimeSpec,&localLeftSpec);#endif}int CheckSocketError(int nResult){// 检查非阻塞套接字错误 if(nResult>0) return 0; if(nResult==0) return 1;#if !defined(_WIN32)&&!defined(_WIN64) if(errno==EAGAIN) return 0; return 1;#else if(WSAGetLastError()==WSAEWOULDBLOCK) return 0; else return 1;#endif}int SocketWrite(int nSocket,char * pBuffer,int nLen,int nTimeout){ int nOffset=0; int nWrite; int nLeft=nLen; int nLoop=0; int nTotal=0; int nNewTimeout=nTimeout*10; while((nLoop<=nNewTimeout)&&(nLeft>0)) { nWrite=send(nSocket,pBuffer+nOffset,nLeft,0); if(nWrite==0) { return -1; }#if defined(_WIN32)||defined(_WIN64) if(nWrite==SOCKET_ERROR) { if(WSAGetLastError()!=WSAEWOULDBLOCK) { return -1; } }#else if(nWrite==-1) { if(errno!=EAGAIN) { return -1; } }#endif if(nWrite<0) { return nWrite; } nOffset+=nWrite; nLeft-=nWrite; nTotal+=nWrite; if(nLeft>0) {// 延时100ms SysSleep(100); } nLoop++; } return nTotal;}int SocketRead(int nSocket,void * pBuffer,int nLen){ if(nSocket==-1) return -1; int len=0;#if defined(_WIN32)||defined(_WIN64) len=recv((SOCKET) nSocket,(char *)pBuffer,nLen,0);#else len=recv(nSocket,(char *)pBuffer,nLen,0);#endif if(len==0) { return -1; } if(len==-1) {#if defined(_WIN32)||defined(_WIn64) int localError=WSAGetLastError(); if(localError==WSAEWOULDBLOCK) return 0; return -1;#else if(errno==0) return -1; if(errno==EAGAIN) return 0;#endif return len; } if(len>0) return len; else return -1;}void EndClient(void * pParam){ CLIENT_PARAM * localParam=(CLIENT_PARAM *) pParam; MyLock(); localParam->nEndFlag=1; localParam->pServerParam->pClientSocket[localParam->nIndexOff]=-1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -