Bug(1)

程序要求:内网之间客户端截屏(.bmp)并传送给服务端。

server:

#include <winsock2.h>    // 为了使用Winsock API函数
#include <stdio.h>
#include <windows.h>
 #include<fstream> 
using namespace std;

// 告诉连接器与WS2_32库连接
#pragma comment(lib,"WS2_32.lib")

DWORD rem=0,num=0;
void stranl(char *_str)
{
    char _rem[16];
    char _num[32];
    int i,j=0;
    for(i=0;_str[i]!='#';i++)
    {
        _num[i]=_str[i];
    }
    _num[i]='\0';
    i++;
    for(;_str[i]!='\0';i++)
    {
        _rem[j]=_str[i];
        j++;
    }
    _rem[j]='\0';
    num=atoi(_num);
    rem=atoi(_rem);

}
int main(int argc, char* argv[])
{
    // 初始化WS2_32.dll
    WSADATA wsaData;
    WORD sockVersion = MAKEWORD(2, 0);
    ::WSAStartup(sockVersion, &wsaData);
    
    // 创建套节字
    SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(s == INVALID_SOCKET)
    {
        printf("Failed socket() \n");
        ::WSACleanup();
        return 0;
    }
    
    // 填充sockaddr_in结构
    sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(8888);
    sin.sin_addr.S_un.S_addr = INADDR_ANY;
    
    // 绑定这个套节字到一个本地地址
    if(::bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
    {
        printf("Failed bind() \n");
        ::WSACleanup();
        return 0;
    }
    
    // 进入监听模式
    if(::listen(s, 2) == SOCKET_ERROR)
    {
        printf("Failed listen()");
        ::WSACleanup();
        return 0;
    }
    
    // 循环接受客户的连接请求
    sockaddr_in remoteAddr; 
    int nAddrLen = sizeof(remoteAddr);
    SOCKET client;
    char szCmd[32];
    char szNumRem[32];
    int i;
    char block[1024];
    int BlkSize=0,allNum=0;
    char *allData=NULL;
    DWORD BmpSize=0;
    int nSize=0;
    while(TRUE)
    {
        // 接受一个新连接
        client = ::accept(s, (SOCKADDR*)&remoteAddr, &nAddrLen);
        if(client == INVALID_SOCKET)
        {
            printf("Failed accept()");
            continue;
        }
        
        printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));
        while(1)
        {
            printf("请输入命令:\n");
            scanf("%s",szCmd);
            //分析命令
            if(0!=strcmp(szCmd,"q"))  //如果不是退出命令,则:
            {
                if(0==strcmp(szCmd,"scrshot")) // 如果是截屏命令,则:
                {
                    // 向客户端发送命令,让其做好准备
                    ::send(client, szCmd, strlen(szCmd), 0);
                    nSize = ::recv(client, szNumRem, 32, 0);
                    if(nSize > 0)
                    {
                         szNumRem[nSize]='\0';
                        //解析字符串
                         printf("字符串:%s,大小:%d\n",szNumRem,nSize);
                         stranl(szNumRem);
                         printf("次数:%d,余数:%d\n",num,rem);
                         BmpSize=num*1024+rem;
                         allData = new char[BmpSize];
                    }
                    printf("输入开始命令:");
                    scanf("%s",szCmd);
                    ::send(client, szCmd, strlen(szCmd), 0);
                    for(i=0;i<num;i++)
                    {
                        BlkSize = ::recv(client, block, 1024, 0);
                        //if(BlkSize==1024)
                        if(1)
                        {
                            memcpy(allData+1024*i,block,1024);
                        }
                        else
                        {
                            printf("我擦!\n");
                            system("pause");
                        }
                    }
                    BlkSize = ::recv(client, block, 1024, 0);
                    if(BlkSize==rem)
                    {
                        memcpy(allData+1024*i,block,rem);
                    }
                    ofstream of("ClicentScreenShot.bmp",ios_base::binary);
                    of.write(allData,BmpSize);
                    printf("已完全接收图片!\n");
                }
            }
            else
                break;
        }
        // 关闭同客户端的连接
        ::closesocket(client);
     }
        
    // 关闭监听套节字
    ::closesocket(s);
    // 释放WS2_32库
    ::WSACleanup();    

    return 0;
}

client:

#include <winsock2.h>    // 为了使用Winsock API函数
#include <stdio.h>
#include <windows.h>
#include<fstream>
using namespace std; 

// 告诉连接器与WS2_32库连接
#pragma comment(lib,"WS2_32.lib")

char *allData=NULL;
DWORD BmpSize=0;
int main(int argc, char* argv[])
{
    // 初始化WS2_32.dll
    WSADATA wsaData;
    WORD sockVersion = MAKEWORD(2, 0);
    ::WSAStartup(sockVersion, &wsaData);
    
    // 创建套节字
    SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(s == INVALID_SOCKET)
    {
        printf("Failed socket() \n");
        ::WSACleanup();
        return 0;
    }

    // 也可以在这里调用bind函数绑定一个本地地址
    // 否则系统将会自动安排

    // 填写远程地址信息
    sockaddr_in servAddr; 
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons(8888);
    // 注意,这里要填写服务器程序(10ServerDemo程序)所在机器的IP地址
    // 如果你的计算机没有联网,直接使用127.0.0.1即可
    servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

    if(::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1)
    {
        printf("Failed connect() \n");
        ::WSACleanup();
        return 0;
    }
    
    
    // 接收命令
    char szCmdBuff[32];
    char str[32];
    char tmp[16];
    int i,j;
    char block[1024];
    int nRecv = ::recv(s, szCmdBuff, 32, 0);
    if(nRecv > 0)
    {
        szCmdBuff[nRecv] = '\0';
        printf("接收到命令:%s\n", szCmdBuff);
    }
    //命令处理
     if(0==strcmp(szCmdBuff,"scrshot")) 
     {
         //截屏,并计算图像大小
         _ScreenSnap();
         //每次发送1024字节,计算发送次数及剩余字节数
         //格式: 次数#余数
         DWORD rem=BmpSize%1024;
         DWORD num=BmpSize/1024;
         itoa(num,str,10);
         strcat(str,"#");
         itoa(rem,tmp,10);
         strcat(str,tmp);
         printf("字符串:%s\n",str);
         ::send(s, str, strlen(str), 0);
         ::recv(s, szCmdBuff, 32, 0);
         if(0==strcmp(szCmdBuff,"start"))
         {
            for(i=0;i<num;i++)
            {
                for(j=0;j<1024;j++)
                    block[j]=allData[i*1024+j];
                ::send(s,block,1024,0);
            
             }
            for(j=0;j<rem;j++)
                    block[j]=allData[num*1024+j];
             ::send(s,block,num,0);
         }
     }
    // 关闭套节字
    ::closesocket(s);
    // 释放WS2_32库
    ::WSACleanup();    
    return 0;
}

结果:

posted @ 2014-04-17 15:13  乾卦  阅读(177)  评论(0编辑  收藏  举报