首页 > 解决方案 > C++ 有没有我可以在 WinSock 中为 recv 函数设置生命周期?

问题描述

这是我接受和接受的代码 int sock = createSocket(); int rc = ::bind(sock, glDispenserServerConfig->m_szServerPort);

sockaddr_in clientAddr;
int clientAddrSize = sizeof(clientAddr);
int clientSock;
bool saveImage;
while (-1 != (clientSock = accept(sock,(sockaddr*)&clientAddr, (socklen_t*)&clientAddrSize))) {
        string requestStr;
        int bufSize = 5;
        requestStr.resize(bufSize); 
      
        string data = "";
        string::size_type position;
        bool getFlag = false;
        while(1) {
            recv(clientSock, &requestStr[0], bufSize, 0);
            data += requestStr;
            // position = data.find("}");
            if(requestStr[0] == '}') 
                break;
            else if(requestStr[1] == '}')
                break;
            else if(requestStr[2] == '}')
                break;
            else if(requestStr[3] == '}')
                break;
            else if(requestStr[4] == '}')
                break;
            if(requestStr[0] == 'G' && requestStr[1] == 'E' && requestStr[2] == 'T' && requestStr[3] == ' ') {
                getFlag = true;
                for(int i = 0; i < 20; i++) {
                    recv(clientSock, &requestStr[0], bufSize, 0);
                    data += requestStr;
                }
                break;
            }
        }

并使用了两个功能:

int createSocket() {
    int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sock == -1) {
            printf("Create socket failed!\n");
        }
        return sock;
    }


bool bind(int &sock, unsigned short port) {
    if (sock <= 0) {
        createSocket();
    }

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port); 
    addr.sin_addr.s_addr = htons(0); 

    if (::bind(sock, (sockaddr*)&addr, sizeof(addr)) != 0) {    
        printf("bind port %d failed!\n", port);
        return false;
    }
    printf("bind port %d succeeded.\n", port);
    listen(sock, 10);
    return true;
}

我试图从 POST 请求中获取数据流。由于身体的大小是未知的,我做了一个循环来读取整个身体。这个端口是为获取 POST 请求而设计的,所以我打破了循环并制作了一个标志以供以后使用。我的问题是我在这里检查结尾符号“}”。我担心有时如果缺少结束符号,服务器将被 recv 函数阻止。所以我想知道是否有某种方法可以设置 recv 最大等待时间,比如 2 秒它没有从缓冲区读取任何内容然后打破循环并继续?

标签: c++socketshttpserverrecv

解决方案


根据Remy Lebeau的评论,这是我的新代码:

sockaddr_in clientAddr;
    int32 clientAddrSize = sizeof(clientAddr);
    int32 clientSock;
    bool saveImage;
    struct timeval timeout;
    socklen_t len = sizeof(timeout);
    timeout.tv_sec = 10;
    timeout.tv_usec = 0;
    while (-1 != (clientSock = accept(sock, (sockaddr*)&clientAddr, (socklen_t*)&clientAddrSize))) {
        int err = setsockopt(clientSock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout.tv_sec, sizeof(struct timeval));

这将在 10 秒内停止被 recv 阻塞


推荐阅读