windows平台probuf协议socket通信例子

2/22/2017来源:ASP.NET技巧人气:2842

#include "common/op_socket.h"  
#include "people.pb.h"  
#PRagma comment(lib, "libprotobuf.lib")  
#pragma comment(lib, "libprotoc.lib")  
using namespace std;  
int main()     
{     
    GOOGLE_PROTOBUF_VERIFY_VERSION;  
    OP_SOCKET server_sockfd;  
    OP_SOCKET new_server_sockfd;  
    OP_SOCKADDR_IN server_addr;  
    OP_SOCKADDR_IN client_addr;  
    OP_SOCKLEN_T sin_size;  
    char buffer[BUFFER_SIZE + 1];  
    int bytes;  
    string str;  
    string data;  
    CPFS::People p;  
#ifdef WIN32  
    WSADATA  Ws;  
    //Init Windows Socket  
    if (WSAStartup(MAKEWord(2,2), &Ws) != 0)  
    {  
        fprintf(stderr, "Init Windows Socket Failed::%s", GetLastError());  
        return EXIT_FAILURE;  
    }  
#endif  
    server_sockfd = op_socket(AF_INET, SOCK_STREAM, 0);   
    op_set_sockaddr_in(server_addr, AF_INET, htons(INADDR_ANY), htons(OP_PORT));  
    op_bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));     
    op_listen(server_sockfd, LISTEN_QUEUE);     

    while(1)  
    {     
        sin_size = sizeof(struct sockaddr_in);  
        new_server_sockfd = op_accept(server_sockfd, (struct sockaddr *)&client_addr, &sin_size);  

        bytes = op_recv(new_server_sockfd, buffer, BUFFER_SIZE, 0);  
        buffer[bytes] = '/0';  
        str = buffer;  
        cout << "You got a message from " << inet_ntoa(client_addr.sin_addr) << endl;  
        cout << "client_addr Message: " << str << endl;  
        if(str == "get")  
        {  
            p.set_id(1);  
                p.set_name("monkey");  
                p.set_email("[email protected]Gmail.com");  
                p.SerializeToString(&data);  
            char dst[BUFFER_SIZE];  
            strcpy(dst, data.c_str());  
                op_send(new_server_sockfd, dst, sizeof(dst), 0);  
        }  
        else  
        {  
            op_send(new_server_sockfd, "Fucking client_addr!/n", 16, 0);  
        }  
        op_close(new_server_sockfd);  
    }     
    op_close(server_sockfd);  
    google::protobuf::ShutdownProtobufLibrary();  
    getchar();  
#ifdef WIN32  
    WSACleanup();  
#endif  
    return EXIT_SUCCESS;  
}  123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566

#include "stdafx.h"
#include <stdio.h>  
#include <winsock2.h>  
#include "tag_message.h"
#include <windows.h>
#include "minilzo.h"
#include <iostream>
#include <sstream>
#pragma comment(lib,"ws2_32.lib")  
/*#pragma comment(lib, "../lib/libprotobuf.lib")  */
using namespace std;
#pragma warning(disable:4996)
#include <iostream>



#include <time.h>
#ifdef WIN32
#   include <windows.h>
#pragma comment(lib, "winmm.lib ")
#else
#   include <sys/time.h>
#endif
#ifdef WIN32
int
gettimeofday(struct timeval *tp, void *tzp)
{
    time_t clock;
    struct tm tm;
    SYSTEMTIME wtm;
    GetLocalTime(&wtm);
    tm.tm_year     = wtm.wYear - 1900;
    tm.tm_mon     = wtm.wMonth - 1;
    tm.tm_mday     = wtm.wDay;
    tm.tm_hour     = wtm.wHour;
    tm.tm_min     = wtm.wMinute;
    tm.tm_sec     = wtm.wSecond;
    tm.tm_isdst    = -1;
    clock = mktime(&tm);
    tp->tv_sec = clock;
    tp->tv_usec = wtm.wMilliseconds * 1000;
    return (0);
}
#endif

string tirm_number(int n)
{
    stringstream _ss;
    _ss.str("");
    if (n < 10)
    {
        _ss << "0" << n;
    }
    else
    {
        _ss << n;
    }
    return _ss.str();
}


unsigned int g_increase_id = 1000;
string get_uuid(string server_name)
{       
    stringstream _ss;
    _ss.str("");

    if (g_increase_id++ > 2000)
    {
        g_increase_id = 1000;
    }

    struct tm *ptr; 
    time_t lt; 

    lt = time(NULL); 
    ptr = localtime(&lt); 

    _ss << server_name  << ptr->tm_year<<tirm_number(ptr->tm_mon) << tirm_number(ptr->tm_mday);
    _ss << tirm_number(ptr->tm_hour) << tirm_number(ptr->tm_min) << tirm_number(ptr->tm_sec);
    _ss << g_increase_id;

    return _ss.str();
}
void make_pack(NET_C2L_proof &packet)
{
    packet.dw_world_name_crc = 100010;
    packet.dwCurVersionID    = 10001;
    packet.dwType            = 1;
    strncpy(packet.szUserName,"jxf002",6);
    strncpy(packet.szPSD,"111111",6);
    strncpy(packet.szGUID,"111111",6);
}

int sock_connect(SOCKET &soc, SOCKADDR_IN &serveraddr)
{
    if((soc = socket(AF_INET, SOCK_STREAM, ipPROTO_TCP)) <= 0) 
    {  
        printf("Create socket fail!\n");  
        return -1;  
    }  

    serveraddr.sin_family = AF_INET;  
    serveraddr.sin_port = htons(4303);  
    serveraddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  

    bool is_connected = true;
    printf("Try to connect...\n");  
    if(connect(soc, (SOCKADDR *)&serveraddr, sizeof(serveraddr)) != 0)  
    {  
        printf("Connect fail!\n");  
        is_connected = false;
        return 0;
    }
    else
    {
        printf("Connected\n");
    }
    return 1;

}

int get_input()
{
    char buf[1024];
    int ret = 0;
    while(true)
    {
        cout << "please enter command: [close] [retry]" << endl;
        cin.getline(buf, 50);
        if(strstr(buf,"close"))
        {
            break;  
        }
        else if(strstr(buf,"retry"))
        {
            ret = 1;
            break;
        }
        else
        {
            cout << "Invalid command:" << buf << endl;
        }
    }
    return ret;
}

void socket_receive(SOCKET &m_socket)
{
    unsigned int tempsz = 0;
    unsigned int msgsz = 0;
    int nresult = 0;
    char* temPPTr = NULL;
    tempsz = sizeof(unsigned int);
    tempptr = (char*)&msgsz;
    while(tempsz > 0)
    {

            nresult = ::recv(m_socket, tempptr, tempsz, 0);
            if(0 == nresult)
            {
                return;
            }
            if(SOCKET_ERROR == nresult)
            {
                return;
            }
            else
            {
                tempsz -= nresult;
                if (tempsz<0)
                    break;
                tempptr += nresult;
            }
    }

    if(SOCKET_ERROR != nresult)
    {
        char* bufin = new char[msgsz + msgsz/64 + 64];
        tempsz = sizeof(unsigned int) + msgsz;
        tempptr = bufin;
        while(tempsz > 0)
        {
            timeval blocktime;
            blocktime.tv_sec = 0;
            blocktime.tv_usec = 150*1000;
            fd_set fdread;
            FD_ZERO(&fdread);
            FD_SET(m_socket, &fdread);
            int n = ::select(m_socket+1, &fdread, NULL, NULL, &blocktime);
            if(n == 1)
            {
                nresult = ::recv(m_socket, tempptr, tempsz, 0);
                if(0 == nresult)
                {
                    return;
                }
                if(nresult == SOCKET_ERROR)
                {
                    return;
                }
                else
                {
                    tempsz -= nresult;

                    if (tempsz<0)
                        break;
                    tempptr += nresult;
                }
            }

        }

        unsigned int osz = *(unsigned int*)bufin;
        unsigned char* buflzo = new unsigned char[osz];
        lzo_uint sz = osz;

        lzo1x_decompress((unsigned char*)(bufin + sizeof(unsigned int)), msgsz, buflzo, &sz,NULL);
        try
        {
            NET_L2C_proof_result *packet = (NET_L2C_proof_result*)(buflzo);
            cout << packet->dw_error_code << endl;
        }
        catch(...)
        {
            cout << "Packet error" << endl;
        }       
    }

}

bool socket_send(int connect_result, SOCKET m_socket)
{
    NET_C2L_proof packet;
    make_pack(packet);
    char buf[1024];

    bool need_re_connect = false;
    while(!need_re_connect && connect_result)  
    {  

        int nreturn = 0;
        unsigned int headsz = sizeof(unsigned int);
        char* header = (char*)&packet.dw_size;
        while(headsz > 0)
        {
            nreturn = send(m_socket, header, headsz, 0);
            if(SOCKET_ERROR == nreturn)
            {
                int err_no = WSAGetLastError();
                printf("[HEAD]send error,(%d,%d)\n",nreturn,err_no);
                Sleep(2000);
                WSACleanup();  
                need_re_connect = true;
                break;
            }
            else
            {
                header += nreturn;
                headsz -= nreturn;
            }
            cout <<"[HEAD] " << nreturn <<","<< headsz << endl; 
        }
        unsigned int sz = packet.dw_size;
        unsigned char* data(NULL);
        data = (unsigned char*)&packet;
        while(sz > 0)
        {
            if(!data)
                break;
            nreturn = ::send(m_socket, (char*)data, sz, 0);
            if(SOCKET_ERROR == nreturn)
            {
                int err_no = WSAGetLastError();
                printf("[BODY]send error,(%d,%d)\n",nreturn,err_no);
                Sleep(2000);
                WSACleanup();  
                need_re_connect = true;
                break;
            }
            else
            {
                data += nreturn;
                sz -= nreturn;
            }
            cout <<"[BODY] " << nreturn <<","<< sz << endl;
        }
        if(need_re_connect)
        {
            break;
        }
        socket_receive(m_socket);
        Sleep(1000);
    }
    Sleep(2000);
    return need_re_connect;
}

int main()  
{  
    SOCKET soc;  
    SOCKADDR_IN serveraddr;  
    SOCKADDR_IN clientaddr;  

RE_CONNECT: 
    WSADATA wsa;  
    WSAStartup(MAKEWORD(1,1),&wsa); 

    int connect_result = sock_connect(soc, serveraddr);
    bool socket_error = socket_send(connect_result, soc);

    WSACleanup();

    if (socket_error)
    {
        goto RE_CONNECT;
    }

    if(get_input() == 1)
    {
        goto RE_CONNECT;
    }
    return 0;  
}