MFC中socket编程时recv设置超时属性后,如果超时返回值是啥?谢谢大家:)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC中socket编程时recv设置超时属性后,如果超时返回值是啥?谢谢大家:)相关的知识,希望对你有一定的参考价值。

MFC中socket编程时recv设置超时属性后,如果超时返回值是什么?

超时,也是 返回: SOCKET_ERROR
用WSAGetLastError() 获取 id 再分析,程序如下:

memset(buff,0x0,buff_size);
if (recv(sock,buff,sizeof(buff),0) == SOCKET_ERROR)
id = WSAGetLastError();
switch (id)

case WSANOTINITIALISED: printf("not initialized\\n"); break;
case WSASYSNOTREADY: printf("sub sys not ready\\n"); break;
case WSAHOST_NOT_FOUND: printf("name server not found\\n"); break;
case WSATRY_AGAIN: printf("server fail\\n"); break;
case WSANO_RECOVERY: printf("no recovery\\n"); break;
case WSAEINPROGRESS: printf("socket blocked by other prog\\n"); break;
case WSANO_DATA: printf("no data record\\n"); break;
case WSAEINTR: printf("blocking call canciled\\n"); break;
case WSAEPROCLIM: printf("limit exceeded\\n");
case WSAEFAULT: printf("lpWSAData in startup not valid\\n");
default: printf("unknown error id = %d\\n",id); break;
;
printf("receive error.\\n");
;
参考技术A SOCKET ERROR

linux网路编程--网络超时检测

网络超时检测(1)

  设置socket的属性SO_RCVTIMEO

参考代码:

struct timeval tv;

tv..tv_sec=5;//设置5s时间

tv.tv_usec=0;

setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv));//设置接收超时

recv/recvfrom

网络超时检查(2)

  用select检测socket是否‘ready’

参考代码:

struct fd_set rdfds;

struct timeval tv={5,0};

FD_ZERO(&rdfds);

FD_SET(sockfd,&rdfds);

if(selecet(sockfd+1,&rdfs,NULL,NULL,&tv)>0)//socket准备就绪

{

  recv/recvfrom

}

 

selct-timeout.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>

#define  N  128
#define err_log(errlog) do{perror(errlog);exit(1);}while(0)

int main(int argc, const char *argv[])
{
    fd_set readfds;
    int maxfd;
    int i = 0;
    char buf[N] = {};
    int ret;

    int sockfd;
    int acceptfd;
    struct sockaddr_in serveraddr, clientaddr;
    socklen_t addrlen = sizeof(clientaddr);

    if(argc < 3)
    {
        fprintf(stderr, "Usage:%s serverip port.\\n", argv[0]);
    }
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        err_log("fail to socket");
    }

    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));

    if(bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
    {
        err_log("fail to bind");
    }

    if(listen(sockfd, 5) < 0)
    {
        err_log("fail to listen");
    }

    FD_ZERO(&readfds);
    maxfd = sockfd;

    struct timeval tv;

    while(1)
    {
        FD_SET(0, &readfds);
        FD_SET(sockfd, &readfds);

        tv.tv_sec = 5;
        tv.tv_usec = 0;

        if((ret = select(maxfd+1,&readfds, NULL, NULL,&tv)) < 0)
        {
            err_log("fail to select");
        }
        printf("After select.\\n");

        switch(ret)
        {
        case 0:
            printf("Timeout....\\n");
            break;
        default :
            for(i = 0; i < maxfd+1; i++)
            {
                if(FD_ISSET(i, &readfds))
                {
                    if(i == 0)
                    {
                        fgets(buf, N, stdin);
                        printf("buf:%s", buf);
                    }
                    if(i == sockfd)
                    {
                        if((acceptfd = accept(sockfd, (struct sockaddr*)&clientaddr, &addrlen)) < 0)
                        {
                            err_log("fail to accept");
                        }
                        printf("%s --> %d --> acceptfd = %d\\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), acceptfd);
                    }

                }
            } // end default
        } // endswitch
    }
    
    return 0;
}

 

网络超时(3)

设置定时器(timer),捕捉SIGALRM信号

参考代码:

  void handler(int signo){return;}

//一旦进程收到这个信号,执行完信号处理函数之后,下一个函数就会直接返回,不阻塞在哪里

struct sigaction act;

sigaction(SIGALRM,NULL,&act);

act.sa_handler=handler

act.sa_flag&=~SA_RESTART;

sigaction(SIGALRM,&act,NULL);

alarm(5)

if(recv(...)<0)....

 

server-alarm.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <errno.h>

#define  err_log(errlog)  do{perror(errlog); exit(1);}while(0)
#define  N  128

// ./server  192.168.0.196  10000

void handler(int sig)
{
    printf("timeout....\\n");
}

int main(int argc, const char *argv[])
{
    int sockfd;
    int confd;
    struct sockaddr_in  serveraddr, clientaddr;
    char buf[N] = {};

    if(argc != 3)
    {
        fprintf(stderr, "Usage:%s serverip port.\\n", argv[0]);
        return -1;
    }

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        err_log("fail to socket");
    }

    printf("sockfd = %d\\n", sockfd);

    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));

    if(bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
    {
        err_log("fail to bind");
    }

    if(listen(sockfd, 10) < 0)
    {
        err_log("fail to listen");
    }

    socklen_t addrlen = sizeof(struct sockaddr);
    if((confd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) < 0)
    {
        err_log("fail to accept");
    }

    printf("confd = %d , %s --> %d \\n", confd , inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
    
    struct sigaction act;

    sigaction(SIGALRM, NULL, &act);

    act.sa_handler = handler;
    act.sa_flags &= ~SA_RESTART;

    sigaction(SIGALRM, &act, NULL);


    while(1)
    {
        alarm(5);
        if(recv(confd, buf, N, 0) < 0)
        {
            if(errno == 4)
            {
                printf("errno = %d\\n", errno);
            }
            else
            {
                err_log("fail to recv");
            }
        }
        printf("From client:%s\\n", buf);

    }

    close(sockfd);

    return 0;
}

 

编译运行,如果客户端5秒不输入,则可以看到

 

以上是关于MFC中socket编程时recv设置超时属性后,如果超时返回值是啥?谢谢大家:)的主要内容,如果未能解决你的问题,请参考以下文章

linux网路编程--网络超时检测

如何在python的socket recv方法上设置超时?

如何在 python 的 socket recv 方法上设置超时?

windows下对socket的send和recv的超时设置,并附一个简洁明了的socket简单demo

在Python3中,socket.recv方法如果一段时间内没有收到返回,如何让这段代码跳过,并执行下一步操作

socket编程·send和recv