博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
windows linux—unix 跨平台通信集成控制系统
阅读量:5156 次
发布时间:2019-06-13

本文共 15286 字,大约阅读时间需要 50 分钟。

首先,我们可以用到这个开源的开发包:

mdk(Micro-Development-Kit)微量级软件开发包,提供几个常用类,主要实现了一个高性能的并发服务器引擎 

  使用c++开发,是一个跨平台的开发包,支持linux32/linux64/win32/win64的类库  。

  mdk服务器引擎,提出面向业务的服务器开发模式,根据服务器业务层最关心的3件事,抽象出连接发生(OnConnect),消息到达(OnClose),连接关闭(OnClose)3个接口,让服务器端开发者可以全身心的投入业务逻辑的开发中。 

特点:        提供分布式支持,自身是一个server-client的结合体(即做服务器使用的同时,也可以像client一样去连接别的服务器,组成分布式系统),并且io接口统一到onconnect onmsg onclose中,不必区别对待        事件轮巡使用的是原生epoll iocp实现,确保了对io响应速度的完全掌控        几乎等同于lock free的并发算法,保证并发效率        欢迎大家共同学习使用。

 

或者是这里:

 

 

 我们写客户端的时候可以用到里面 的socket类

socket.h如下:

// Socket.h: interface for the Socket class./////***********************************************************************************************************************************************/#ifndef MDK_SOCKET_H#define MDK_SOCKET_H#include 
using namespace std;#ifdef WIN32#include
#define socklen_t int#else#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INVALID_SOCKET -1#define SOCKET_ERROR -1#define closesocket closetypedef int SOCKET;#endif#include
#include
#include
namespace mdk{class Socket{public: enum SocketError { seTimeOut = -2, seSocketClose = -1, seError = -3, }; enum protocol { tcp = SOCK_STREAM, udp = SOCK_DGRAM, }; Socket(); Socket( SOCKET hSocket, protocol nProtocolType ); virtual ~Socket(); public: // SOCKET GetSocket(); /* */ bool Init(protocol nProtocolType); /** */ void Close(); // bool IsClosed(); // /* TCP */ int Send( const void* lpBuf, int nBufLen, int nFlags = 0 ); /* */ int Receive( void* lpBuf, int nBufLen, bool bCheckDataLength = false, long lSecond = 0, long lMinSecond = 0 ); // /*UDP */ int SendTo( const char *strIP, int nPort, const void* lpBuf, int nBufLen, int nFlags = 0 ); /* */ int ReceiveFrom( char* lpBuf, int nBufLen, std::string &strFromIP, int &nFromPort, bool bCheckDataLength = false, long lSecond = 0, long lMinSecond = 0 ); /* */ bool Connect( const char* lpszHostAddress, unsigned short nHostPort ); /* */ bool StartServer( int nPort ); /* */ bool Accept(Socket& rConnectedSocket); // void GetWanAddress( std::string& strWanIP, int& nWanPort ); // void GetLocalAddress( std::string& strWanIP, int& nWanPort ); /* */ bool SetSockMode( bool bWait = false ); /* */ bool SetSockOpt( int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel = SOL_SOCKET ); /* */ static bool SocketInit(void *lpVoid = NULL); static void SocketDestory(); // void GetLastErrorMsg( std::string &strError ); // // static bool InitForIOCP( SOCKET hSocket ); /* */ void Attach( SOCKET hSocket ); /* */ SOCKET Detach(); // // bool InitWanAddress(); // // bool InitLocalAddress(); protected: /* */ bool TimeOut( long lSecond, long lMinSecond ); // bool WaitData(); /* */ void GetAddress( const sockaddr_in &sockAddr, std::string &strIP, int &nPort ); /* */ bool Bind( unsigned short nPort, char *strIP = NULL ); /* */ bool Listen( int nConnectionBacklog = SOMAXCONN ); public:private: SOCKET m_hSocket;// bool m_bBlock;// bool m_bOpened;// sockaddr_in m_sockAddr; std::string m_strWanIP; int m_nWanPort; std::string m_strLocalIP; int m_nLocalPort;};}//namespace mdk#endif // MDK_SOCKET_H

 

socket.cpp的实现:

// Socket.cpp: implementation of the Socket class.////#include 
#include
#include "Socket.h"#ifdef WIN32//#include
#pragma comment ( lib, "ws2_32.lib" )#endifusing namespace std;namespace mdk{Socket::Socket(){ m_hSocket = INVALID_SOCKET; m_bBlock = true; m_bOpened = false;//}Socket::Socket( SOCKET hSocket, protocol nProtocolType ){ m_hSocket = hSocket; m_bBlock = true; m_bOpened = false;// Init(nProtocolType); InitWanAddress(); InitLocalAddress();}Socket::~Socket(){}/**/bool Socket::SocketInit(void *lpVoid){#ifdef WIN32 // initialize Winsock library WSADATA *lpwsaData = (WSADATA *)lpVoid; WSADATA wsaData; if (lpwsaData == NULL) lpwsaData = &wsaData; WORD wVersionRequested = MAKEWORD(1, 1); __int32 nResult = WSAStartup(wVersionRequested, lpwsaData); if (nResult != 0) return false; if (LOBYTE(lpwsaData->wVersion) != 1 || HIBYTE(lpwsaData->wVersion) != 1) { WSACleanup(); return false; }#endif return true;}void Socket::SocketDestory(){#ifdef WIN32 WSACleanup();#endif}void Socket::GetLastErrorMsg( string &strError ){ char strErr[1024];#ifdef WIN32 LPSTR lpBuffer; DWORD dwErrorCode = WSAGetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErrorCode, LANG_NEUTRAL, (LPTSTR)&lpBuffer, 0, NULL ); sprintf( strErr, "Socket Error(%ld):%s", dwErrorCode, lpBuffer ); strError = strErr; LocalFree(lpBuffer);#else sprintf( strErr, "socket errno(%d):%s\n", errno, strerror(errno) ); strError = strErr;#endif}bool Socket::InitForIOCP( SOCKET hSocket ){#ifdef WIN32 return 0 == setsockopt( hSocket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&(hSocket), sizeof(hSocket) );#else return true;#endif}//SOCKET Socket::GetSocket(){ return m_hSocket;}void Socket::GetWanAddress( string& strWanIP, int& nWanPort ){ nWanPort = m_nWanPort; strWanIP = m_strWanIP; return;}bool Socket::InitWanAddress(){ assert( INVALID_SOCKET != m_hSocket ); sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); socklen_t nSockAddrLen = sizeof(sockAddr); if ( SOCKET_ERROR == getpeername( m_hSocket, (sockaddr*)&sockAddr, &nSockAddrLen ) ) return false; m_nWanPort = ntohs(sockAddr.sin_port); m_strWanIP = inet_ntoa(sockAddr.sin_addr); return true;}void Socket::GetLocalAddress( string& strWanIP, int& nWanPort ){ nWanPort = m_nLocalPort; strWanIP = m_strLocalIP; return;}bool Socket::InitLocalAddress(){ sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); socklen_t nSockAddrLen = sizeof(sockAddr); if ( SOCKET_ERROR == getsockname( m_hSocket, (sockaddr*)&sockAddr, &nSockAddrLen )) return false; m_nLocalPort = ntohs(sockAddr.sin_port); m_strLocalIP = inet_ntoa(sockAddr.sin_addr); return true;}/**/bool Socket::Init(protocol nProtocolType){ if ( m_bOpened ) return true; if ( m_hSocket == INVALID_SOCKET ) { m_hSocket = socket( PF_INET, nProtocolType, 0 ); if ( m_hSocket == INVALID_SOCKET ) return false; } m_bOpened = true; return m_bOpened;}/**/bool Socket::Connect( const char *lpszHostAddress, unsigned short nHostPort){ assert( NULL != lpszHostAddress ); sockaddr_in sockAddr; memset(&sockAddr,0,sizeof(sockAddr)); sockAddr.sin_family = AF_INET; sockAddr.sin_addr.s_addr = inet_addr(lpszHostAddress); sockAddr.sin_port = htons( nHostPort ); if ( SOCKET_ERROR != connect(m_hSocket, (sockaddr*)&sockAddr, sizeof(sockAddr)) ) { InitWanAddress(); InitLocalAddress(); return true; } return false;}//bool Socket::StartServer( int nPort ){ if ( !this->Bind( nPort ) ) return false; return this->Listen();}//bool Socket::IsClosed(){ return !m_bOpened;}/**/void Socket::Close(){ if ( INVALID_SOCKET == m_hSocket ) return; if ( m_bOpened ) { closesocket(m_hSocket); m_bOpened = false; } m_hSocket = INVALID_SOCKET; return;}/**/void Socket::Attach(SOCKET hSocket){ m_hSocket = hSocket; m_bBlock = true; m_bOpened = true;// InitWanAddress(); InitLocalAddress();}/**/SOCKET Socket::Detach(){ SOCKET hSocket = m_hSocket; m_hSocket = INVALID_SOCKET; m_bBlock = true; m_bOpened = false;// return hSocket;}/**/int Socket::Receive( void* lpBuf, int nBufLen, bool bCheckDataLength, long lSecond, long lMinSecond ){ if ( TimeOut( lSecond, lMinSecond ) ) return seTimeOut;//³¬Ê± int nResult; int nFlag = 0; if ( bCheckDataLength ) nFlag = MSG_PEEK; nResult = recv(m_hSocket, (char*)lpBuf, nBufLen, nFlag); if ( 0 == nResult ) return seSocketClose;// if ( SOCKET_ERROR != nResult ) return nResult;//ú //socket#ifdef WIN32 int nError = GetLastError(); if ( WSAEWOULDBLOCK == nError ) return 0;// return seError;#else if ( EAGAIN == errno ) return 0;// return seError;#endif}/**/int Socket::Send( const void* lpBuf, int nBufLen, int nFlags ){ int nSendSize = send(m_hSocket, (char*)lpBuf, nBufLen, nFlags); if ( 0 > nSendSize ) {#ifdef WIN32 int nError = GetLastError(); return -1;#else return -1;#endif } if ( nSendSize <= nBufLen ) return nSendSize; return -1;}/**/bool Socket::Bind( unsigned short nPort, char *strIP ){ memset(&m_sockAddr,0,sizeof(m_sockAddr)); m_sockAddr.sin_family = AF_INET; if ( NULL == strIP ) m_sockAddr.sin_addr.s_addr = htonl(INADDR_ANY); else { unsigned long lResult = inet_addr( strIP ); if ( lResult == INADDR_NONE ) return false; m_sockAddr.sin_addr.s_addr = lResult; } m_sockAddr.sin_port = htons((unsigned short)nPort); return (SOCKET_ERROR != bind(m_hSocket, (sockaddr*)&m_sockAddr, sizeof(m_sockAddr)));}/**/bool Socket::Listen( int nConnectionBacklog ){ return (SOCKET_ERROR != listen(m_hSocket, nConnectionBacklog));}/**/bool Socket::Accept(Socket& rConnectedSocket){ assert( INVALID_SOCKET == rConnectedSocket.m_hSocket ); socklen_t sockAddLen = 0; rConnectedSocket.m_hSocket = accept(m_hSocket, NULL, &sockAddLen); if ( INVALID_SOCKET == rConnectedSocket.m_hSocket ) {#ifdef WIN32 if ( WSAEWOULDBLOCK == GetLastError() ) return true;//#else if ( EAGAIN == errno ) return true;//#endif return false;//socket } rConnectedSocket.m_bOpened = true; rConnectedSocket.InitWanAddress(); rConnectedSocket.InitLocalAddress(); return true;}/**/bool Socket::SetSockOpt( int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel){ return ( SOCKET_ERROR != setsockopt( m_hSocket, nLevel, nOptionName, (char *)lpOptionValue, nOptionLen));}/**/bool Socket::TimeOut( long lSecond, long lMinSecond ){ if ( lSecond <= 0 && lMinSecond <= 0 ) return false; // timeval outtime;// outtime.tv_sec = lSecond; outtime.tv_usec =lMinSecond; int nSelectRet;#ifdef WIN32 FD_SET readfds = { 1, m_hSocket }; nSelectRet=::select( 0, &readfds, NULL, NULL, &outtime ); //#else fd_set readfds; FD_ZERO(&readfds); FD_SET(m_hSocket, &readfds); nSelectRet=::select(m_hSocket+1, &readfds, NULL, NULL, &outtime); //#endif if ( SOCKET_ERROR == nSelectRet ) { return true; } if ( 0 == nSelectRet ) // { return true; } return false;}//bool Socket::WaitData(){ int nSelectRet;#ifdef WIN32 FD_SET readfds = { 1, m_hSocket }; nSelectRet=::select( 0, &readfds, NULL, NULL, NULL ); //#else fd_set readfds; FD_ZERO(&readfds); FD_SET(m_hSocket, &readfds); nSelectRet=::select(m_hSocket+1, &readfds, NULL, NULL, NULL); //#endif if ( SOCKET_ERROR == nSelectRet ) { return false; } if ( 0 == nSelectRet ) // { return false; } return true;}/**/bool Socket::SetSockMode( bool bWait ){#ifdef WIN32 m_bBlock = bWait; unsigned long ul = 1; if ( m_bBlock ) ul = 0; else ul = 1; int ret = ioctlsocket( m_hSocket, FIONBIO, (unsigned long*)&ul ); if ( ret == SOCKET_ERROR ) { return false; }#else m_bBlock = bWait; int flags = fcntl( m_hSocket, F_GETFL, 0 ); // if ( !m_bBlock ) fcntl( m_hSocket, F_SETFL, flags|O_NONBLOCK );// else fcntl( m_hSocket, F_SETFL, flags&(~O_NONBLOCK&0xffffffff) );//#endif return true;}/**/int Socket::SendTo( const char *strIP, int nPort, const void* lpBuf, int nBufLen, int nFlags ){ sockaddr_in sockAddr; memset(&sockAddr,0,sizeof(sockAddr)); sockAddr.sin_family = AF_INET; sockAddr.sin_port = htons(nPort); sockAddr.sin_addr.s_addr = inet_addr(strIP); int ret = sendto( m_hSocket, (const char*)lpBuf, nBufLen, nFlags, (sockaddr*)&sockAddr, sizeof(sockaddr)); if (ret < 0) ret = -1; return ret;}/**/int Socket::ReceiveFrom( char* lpBuf, int nBufLen, string &strFromIP, int &nFromPort, bool bCheckDataLength, long lSecond, long lMinSecond ){ strFromIP = ""; nFromPort = -1; if ( 0 >= nBufLen ) return 0; sockaddr_in sockAddr; socklen_t nAddrLen = sizeof(sockaddr); /* waiting for receive data */ int nResult; int nFlag = 0; while ( true ) { if ( TimeOut( lSecond, lMinSecond ) ) return seTimeOut; if ( bCheckDataLength )nFlag = MSG_PEEK; nResult = recvfrom(m_hSocket, lpBuf, nBufLen, nFlag, (sockaddr*)&sockAddr, &nAddrLen); if ( nAddrLen > 0 ) GetAddress(sockAddr, strFromIP, nFromPort); if ( SOCKET_ERROR == nResult ) // {#ifndef WIN32 if ( EAGAIN == errno ) return 0;// return seError;#else int nError = GetLastError(); if ( 0 == nError )// { if ( MSG_PEEK == nFlag )// { recvfrom(m_hSocket, lpBuf, nBufLen, 0, (sockaddr*)&sockAddr, &nAddrLen); } continue; } if ( WSAEWOULDBLOCK == nError ) return 0;// return seError;#endif } break; } return nResult;}void Socket::GetAddress( const sockaddr_in &sockAddr, string &strIP, int &nPort ){ nPort = ntohs(sockAddr.sin_port); strIP = inet_ntoa(sockAddr.sin_addr);}}//namespace mdk

 

 定义一个客户端的经常用的头文件:

 

////  mac.h//  mac_client////  Created by mac mac on 13-5-8.//  Copyright (c) 2013年 __MyCompanyName__. All rights reserved.//#ifndef mac_client_mac_h#define mac_client_mac_h/*1.注意中文标点,编译器不容易察觉2.server 和client端的宏定义大小要统一*//#define MAX_SIZE 1024#define MAX_NAME_LENGTH 64#define MAX_PATH 260            //保持和windows端定义的一样#define MAX_PATH_MAC 256       //苹果的最大长度#define FALSE 0#define TRUE 1#define MAX_SEND_BUFFER 1024*4#define MAX_RECV_BUFFER 1024*4/typedef struct Command //自定义命令结构体{    int order;//命令序号    long datasize;    void * hwnd;//窗口句柄    }Command; typedef struct Server_Address //服务器地址{        char strIP[3][MAX_PATH];//服务器ip    unsigned int uPort[3] ; //服务器端口    char remark[MAX_NAME_LENGTH];}Server_Address;typedef struct _SYS_INFO //到时候得增加备注{    Command         cmd;    char            remark[MAX_NAME_LENGTH];            //备注    char            computer_name[MAX_NAME_LENGTH];     //    char            user_name[MAX_NAME_LENGTH];         //    char            sys_version[MAX_NAME_LENGTH];       //    char            cpu_type[MAX_NAME_LENGTH];          //    char            host_ip_address[MAX_NAME_LENGTH];   //内网ip    char            ip_addresss[MAX_NAME_LENGTH];       //外网ip    char            uuid[MAX_NAME_LENGTH];             //被控端的唯一标识        unsigned int    cpu_num;                            //    unsigned int    mem_total;                          //    int             host_id;                            //}SYS_INFO;enum {    COMMAND_BIGIN = 20000,     //命令开始    TOKEN_ONLINE,              //上线命令    COMMAND_BREAK,             //断开链接    COMMAND_UNINSTALL,         //卸载     COMMAND_MODIFY_REMARK,     //修改备注///    COMMAND_MANAGER_FILE,           //打开文件管理窗口    COMMAND_GET_DIRECTORY,          //获取控制端主机根目录下所有文件信息     COMMAND_GET_REQUEST_DIRECTORY,  //获取双击请求目录中所有文件信息    COMMAND_SEARCH_FILE,            //文件搜索,还没做    COMMAND_WRONG_DIRECTORY,        //目录为空或者不可读    COMMAND_DELETE_FILE,            //删除文件    COMMAND_FILE_CLOSE,             //关闭当前文件管理功能的链接//        COMMAND_MANAGER_CMD,    //打开cmd管理窗口    TOKEN_CMD_NEXT,         //等待下一个命令    COMMAND_SHELL,          //控制端请求的shell命令    COMMAND_SHELL_CLOSE,    //关闭shell//     COMMAND_MANAGER_DOWNLOAD,   //打开文件下载功能    TOKEN_DOWNLOAD_SETUP,   //控制端发送文件下载连接和uuid    COMMAND_GET_FILEDATA,   //请求文件数据    TOKEN_SENT_FILEDATA,    //发送文件数据    TOKEN_CANT_GET_DATA,    //给控制端发送消息文件不可读    COMMAND_MANAGER_UPLOAD,     //开启文件上传    TOKEN_UPLOAD_SETUP,         //接受文件上传连接    COMMAND_SENT_UPLOAD_DATA,   //发送上传文件数据    TOKEN_UPLOAD_DATA,          //请求上传文件数据    TOKEN_UPLOAD_COMPLETE,      //文件上传完成    COMMAND_RUN_PROGARM,        //上传运行的文件        COMMAND_UPLOAD_CLOSE,      //关闭上传进程和连接         };#endif

 

客户端centos下面使用正常,开发环境codeblocks

 客户端下载:

 

服务器windows 7,xp都没有问题,开发环境visual studio 2010

服务端下载:

 

 整体界面:

命令行效果:

文件管理效果:

 

未完待续

转载于:https://www.cnblogs.com/wangyaning/p/4236954.html

你可能感兴趣的文章
邮件和短信验证码
查看>>
(转)Android studio 使用心得(五)—代码混淆和破解apk
查看>>
构建之法阅读笔记03
查看>>
ES5_03_Object扩展
查看>>
Apache-ab 接口性能测试
查看>>
EF 4.1 Code First Walkthrough
查看>>
常用MySQL语法
查看>>
007API网关服务Zuul
查看>>
bzoj 2600: [Ioi2011]ricehub
查看>>
iOS __strong __weak @Strongify @Weakify
查看>>
thinkphp引入PHPExcel类---thinkPHP类库扩展-----引入没有采用命名空间的类库
查看>>
创建数据库,表
查看>>
Luogu 1970 NOIP2013 花匠 (贪心)
查看>>
javascript笔记---貌似大叔
查看>>
去重查询表mysql 中数据
查看>>
工厂模式
查看>>
AngularJS学习之旅—AngularJS 模块(十五)
查看>>
计算机网络基础知识
查看>>
大数据算法:对5亿数据进行排序
查看>>
BZOJ4372: 烁烁的游戏【动态点分治】
查看>>