重叠i/0异步socket模型

来源:互联网 发布:淘宝卖家订单旗子标记 编辑:程序博客网 时间:2024/06/04 19:35
因为相信,每个qq头像亮着的背后,电脑前都坐着一个孤独的人。你的个性签名不再更新,qq头像不再亮,所以我相信你在生活中是开心的。
天桥还是那座天桥,车梁还是会从下面经过,路灯还是两排。只是我们都回不去那样的场景了。错过好几次约会,上班迟到扣了好几次工资,为得到一点成就感,现在放出来。

#include "Socket.h"
#include <iostream>
#include <string>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

#include <winsock2.h>
using namespace boost;
using namespace std;

#define DATA_BUFSIZE     4096          // 接收缓冲区大小

bool Socket::Start(const std::string& host, int port)
{
   
    WSADATA info;
    if (WSAStartup(MAKEWORD(2,0), &info)) {
        throw "Could not start WSA";
    }
    memset(m_web,0,sizeof(m_web));

    if((m_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET){
        printf("创建套接字失败!");
        return false;
    }

    hostent *he;
    if ((he = gethostbyname(host.c_str())) == 0) {
        error = strerror(errno);
        throw error;
        cout<<"连接失败";
    }

    //unsigned long ip;
    //if((ip=inet_addr(host.c_str()))==INADDR_NONE){
    ////7 printf("不合法的IP地址:%s",argv[1]);
    // exit(-1);
    //}
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    // addr.sin_addr.S_un.S_addr = ip;
    addr.sin_addr = *((in_addr *)he->h_addr);
    memset(&(addr.sin_zero), 0, 8);

    if (-1 == connect(m_socket, (sockaddr *) &addr, sizeof(sockaddr))) {
        error = strerror(WSAGetLastError());
        throw error;
        cout<<"连接失败";
    }
}

void Socket::End() {
  WSACleanup();
}

Socket::Socket(const std::string& host, int port)
{
    Start(host,port);
}


Socket::~Socket()

    Close();
    End();
}

void Socket::Close()
{
    closesocket(m_socket);
}

void Socket::SendLine(std::string s) {
    s += '\n';
    //iResult = 
        send(m_socket,s.c_str(),s.length(),0);
}


void Socket::DownloadBody(const std::string& sendData, std::string & recvData)
{
    //    DWORD                dwRecvBytes ;          // 接收到的字符长度
    ZeroMemory(&m_wsaOverlapped, sizeof(WSAOVERLAPPED));      // 置零
    m_wsaOverlapped.hEvent = WSACreateEvent();
   
    DWORD                dwRecvBytes ;          // 接收到的字符长度
    dwRecvBytes = 0;
    SendLine(sendData);
   
    char statusLine[17]="" ;
    DataBuf.len = 17;
    DataBuf.buf = statusLine;
   
    if(WSARecv(m_socket ,&DataBuf,1,&dwRecvBytes,&Flags,& m_wsaOverlapped, NULL) == SOCKET_ERROR)
    {
        if(WSAGetLastError() != WSA_IO_PENDING)
        {
            closesocket(m_socket);
        }
    }
    char * sline   = statusLine;
    //sline = statusLine;
    if (strlen(sline) >0)
    {
        if (strstr(sline,"200 OK") == 0)
        {
            return ;
        }
    }

    boost::function0 <void> f = boost::bind(&Socket::RecvData,this);
    boost::thread thrd(f);
    thrd.join();
}


bool Socket::DownloadHead(const std::string& sendData, std::string & recvData)
{
    SendLine(sendData);

    int iResult;
    //iResult =  send(m_socket,sendData.c_str(),sendData.length(),0);
    //if (iResult == SOCKET_ERROR)
    //{
    //    printf("send failed: %d\n", WSAGetLastError());
    //    closesocket(m_socket);
    //      Close();
    //      return false;
    //  }
    char m_pageHeader = 0;
    std::string  temp;
    do
    {
        iResult = recv(m_socket, &m_pageHeader, 1, 0);
        temp+= m_pageHeader;
    } while( iResult > 0 && temp.find("<")== string::npos);

    if (temp.find("<")!= string::npos)
    {
        cout<<temp;
    }
    m_httpHeader = new HttpHeader((char*)temp.data());
    if (m_httpHeader->GetState())
    {
        return true;
    }
    delete m_httpHeader;
    return false;
}


void Socket::RecvData()
{
    int ret = 0;
    DWORD Flags;
    int time = 0;
    std::string recv;
    int totalRecv = 0;
    while(1)
    {
        DWORD                dwRecvBytes ;          // 接收到的字符长度
        int err;
        Flags = 0;
        DataBuf.len = 5024;
        DataBuf.buf = m_web;
        ret = WSARecv(m_socket, 
            &DataBuf, 
            1, 
            &dwRecvBytes, 
            &Flags, 
            &m_wsaOverlapped, 
            NULL); 
        recv+=DataBuf.buf;
        totalRecv+=dwRecvBytes;

        if ((ret == SOCKET_ERROR) && (WSA_IO_PENDING != (err = WSAGetLastError())))
        {
            if(WSAECONNABORTED == WSAGetLastError())
            {
                wprintf(L"WSARecv failed with error: %d\n", err);
                break;
            }
        }

        ret = WSAWaitForMultipleEvents(1, &m_wsaOverlapped.hEvent ,  TRUE, 1,  FALSE) ;
        if (ret == WSA_WAIT_FAILED || ret == WSA_WAIT_TIMEOUT) 
        { 
            ret = WSAGetLastError();
            break; 
        }

        WSAResetEvent(m_wsaOverlapped.hEvent );
   
        WSAGetOverlappedResult(m_socket, 
            &m_wsaOverlapped,
            &dwRecvBytes, 
            TRUE, 
            &Flags); 
        if (dwRecvBytes == 0) 
        { 
            Close();
            break;
        } 
    }

    cout << "ProcessIO end!" << endl;
}
原创粉丝点击