W5500 如何实现断开重连?

发布于 2020-07-11 16:32:22    浏览:816

基于tcpclient_sample.c,我改为了while(1),会阻塞在recv()函数,如果连接断开连接也不能自动重连。

#define BUFSZ   1024

static const char send_data[] = "This is TCP Client from RT-Thread.\n"; /* 发送用到的数据 */
void tcpclient(int argc, char **argv)
{
    int ret;
    char *recv_data;
    struct hostent *host;
    int sock, bytes_received;
    struct sockaddr_in server_addr;
    const char *url;
    int port;
    struct wiz_socket *wsocket = RT_NULL;

    if (argc < 3)
    {
        rt_kprintf("Usage: tcpclient URL PORT\n");
        rt_kprintf("Like: tcpclient 192.168.12.44 5000\n");
        return;
    }

    url = argv[1];
    port = strtoul(argv[2], 0, 10);

    /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
    host = gethostbyname(url);
    while (1)   //为了断线重连
    {
        rt_thread_delay(1000);
        /* 分配用于存放接收数据的缓冲 */
        recv_data = rt_malloc(BUFSZ);
        if (recv_data == RT_NULL)
        {
            rt_kprintf("No memory\n");
            //return;
            continue;
        }

        /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */
        if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
            /* 创建socket失败 */
            rt_kprintf("Socket error\n");

            /* 释放接收缓冲 */
            rt_free(recv_data);
            //return;
            continue;
        }
        wsocket = wiz_get_socket(sock);

        /* 初始化预连接的服务端地址 */
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(port);
        server_addr.sin_addr = *((struct in_addr *) host->h_addr);
        rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

        /* 连接到服务端 */
        if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
        {
            /* 连接失败 */
            rt_kprintf("Connect fail!\n");
            closesocket(sock);

            /*释放接收缓冲 */
            rt_free(recv_data);
            //return;
            continue;
        }
        else
        {
            /* 连接成功 */
            rt_kprintf("Connect successful, sock=%d. , port=%d\n", sock, wsocket->port);
        }

        while (1)
        {
            /* 从sock连接中接收最大BUFSZ - 1字节数据 */
            bytes_received = recv(sock, recv_data, BUFSZ - 1, 0);
            if (bytes_received < 0)
            {
                /* 接收失败,关闭这个连接 */
                closesocket(sock);
                rt_kprintf("\nreceived error,close the socket.\r\n");

                /* 释放接收缓冲 */
                rt_free(recv_data);
                break;
            }
            else if (bytes_received == 0)
            {
                /* 默认 recv 为阻塞模式,此时收到0认为连接出错,关闭这个连接 */
                closesocket(sock);
                rt_kprintf("\nreceived error,close the socket.\r\n");

                /* 释放接收缓冲 */
                rt_free(recv_data);
                break;
            }

            /* 有接收到数据,把末端清零 */
            recv_data[bytes_received] = '\0';

            /* 在控制终端显示收到的数据 */
            rt_kprintf("\nReceived data = %s ", recv_data);

            /* 发送数据到sock连接 */
            ret = send(sock, send_data, strlen(send_data), 0);
            if (ret < 0)
            {
                /* 接收失败,关闭这个连接 */
                closesocket(sock);
                rt_kprintf("\nsend error,close the socket.\r\n");

                rt_free(recv_data);
                break;
            }
            else
            {
                /* 打印send函数返回值为0的警告信息 */
                rt_kprintf("\n Send warning,send function return %d.\r\n", ret);
            }
        }
    }
    return;
}

查看更多

whj467467222
whj467467222 认证专家 2020-07-14
This guy hasn't written anything yet

你都while1了,怎么退出呢?
楼主可以试试select

2 个回答
一路寻梦
一路寻梦 2021-05-20
This guy hasn't written anything yet

select 写唤醒有问题,也就是它的非阻塞移植是有问题的,还有就是如何在通迅中非法拔掉网线,那真是一场灾难。官方现在还没解决这些问题,只能自己想办法

撰写答案

请登录后再发布答案,点击登录
关注者
0
被浏览
816

发布
问题

分享
好友

手机
浏览

扫码手机浏览