当前位置:编程学习 > C#/ASP.NET >>

C# 编程中如何使用服务端对客户端的桌面监控

假如我不断的对客户端的机子进行截图然后对服务器发送数据?会不会出现数据拥挤
答案:define  CMD_MSG_UP              1 //客户端到服务器端,图形数据
#define  CMD_MSG_DOWN            2 //服务器端到客户端,聊天语句
#define  CMD_CHECK_LINK          3 //服务器端到客户端,链路检测
#define  CMD_SEND_IMAGE          4 //服务器端到客户端,发送图像
#define  MAX_IMAGE_SIZE         300*1024
#define  MAX_TEXT_SIZE          512
struct MSG_HEAD
{
    unsigned short dwCmdID;
    int   dwLength;
};

struct MSG_UP

    int dwLength;                    
    char szContent[MAX_IMAGE_SIZE];       
};

struct MSG_DOWN
{
    int  dwLength;              
    char szContent[MAX_TEXT_SIZE];         
};

struct MSG_STRUCT
{
    MSG_HEAD MsgHead;
    union
    {
        MSG_UP               MsgUp;
        MSG_DOWN             MsgDown;

    }one;
};
typedef MSG_STRUCT    MESG;

对照上面的协议,看一下我自己写的用于非阻塞模式的读取完整数据包的函数GetPacket():

bool MySocket::GetPacket(void* packet)
{
   
    if( ! packet)
        return false;
    try{
        int read = Receive(mBuffer+mRcvd,1024);
        mRcvd += read;
        //如果缓冲区中不够一个数据包头的长度,则返回。
        if( read < sizeof(MSG_HEAD))
            return false;
      
        //取出数据包头中整个数据包的长度。
        struct MSG_HEAD msgHead;
        memcpy(&msgHead,mBuffer,sizeof(MSG_HEAD));
        int packetLength = msgHead.dwLength;
       
        //如果数据包大于缓冲区长度或者小于0,则肯定不合法,返回并将mRcvd置0。
        if( packetLength > sizeof(MSG_STRUCT) || packetLength <= 0)
        {
            mRcvd = 0;
            return false;
        }

        //如果缓冲区中存在足够数据,则解析数据包并返回。
        if(mRcvd >= packetLength)
        {
            memcpy(packet,mBuffer,packetLength);
            mRcvd -= packetLength;
            memmove(mBuffer,mBuffer+packetLength,mRcvd);
            return true;
        }

        //没有完整数据包,返回假。
        return false;
    }
    catch(Exception &e){
        if(e.ErrorCode() == EOperationWouldBlock){
            return false;
        }
        //若是其他错误则向上层抛出。
        throw;
    }

}

经测试,上面的GetPacket应该不会有问题,而且也不用担心粘包问题,注释比较详细,我就不详解了。

客户端的逻辑模块比较简单,首先不停的连接服务端,20秒一次,直到连接成功。然后不停检查套接字是否可读并根据读取的数据包进行相关操作。代码如下:

DWORD WINAPI WorkThread(LPVOID lparam)
{
    //不断反向连接服务器,直到连接成功,注意这里sock默认是阻塞模式

    while(true)
    {
        try{
            gsocket.Connect(serverIP,5520);
            break;
        }
        catch(Exception &e){
            if(e.ErrorCode() == EAlreadyConnected){
                break;
            }
            else{
                Sleep(20*1000);
                continue;
            }
        }
    }

    //设置为非阻塞模式
    gsocket.SetBlocking(false);
    sset.AddSocket(gsocket);
   
    while(true)
    {
        try{
            sset.Poll(2*1000);
            if(sset.HasActivity(gsocket))
            {
                MESG msg;
                if(gsocket.GetPacket(&msg))
                {
                    if(msg.MsgHead.dwCmdID == CMD_MSG_DOWN)
                    {
                        std::string tmpstr = msg.one.MsgDown.szContent;
                        AfxMessageBox(tmpstr.data());
                    }
                    else if(msg.MsgHead.dwCmdID == CMD_SEND_IMAGE)
                    {
                        DWORD ThreadId;
                        CreateThread(NULL,0,SendImage,0,0,&ThreadId);
                    }
       

上一个:谁有C# 编程 小项目 给我找几个
下一个:这个C#编程题怎么做啊,把代码发给我

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,