简体   繁体   English

TCP服务器似乎无法在LWIP + FreeRTOS中运行

[英]TCP server seems not working in LWIP+FreeRTOS

I have developed a tcp server in my one embedded device using lwip+freeRTOS . 我使用lwip + freeRTOS在我的一个嵌入式设备中开发了一个tcp服务器。 Now this is the flow how I communicate with other device ( Other device has Linux system and let's name it LinuxDevice ) using my device ( let's name it lwipDevice ) 现在,这是我如何与其他设备进行通信的流量(其它设备有Linux系统,让我们将其命名为LinuxDevice)使用我的设备(我们将其命名为lwipDevice)

  1. Send UDP packet from lwipDevice to LinuxDevice to initiate that I am ready to share my information. lwipDevice发送UDP数据包LinuxDevice启动,我愿意分享我的信息。

  2. Now LinuxDevice recognises this message successfully and sends one TCP packet (which contain command) to lwipDevice for telling to send its information. 现在LinuxDevice成功识别此消息并将一个TCP数据包(包含命令)发送到lwipDevice,以告知发送其信息。

  3. But at lwipDevice side this message is not received. 但是在lwipDevice端,没有收到此消息。 So it will not send any response to LinuxDevice . 因此它不会向LinuxDevice发送任何响应。 And steps 1-3 repeat again and again. 并且步骤1-3一次又一次地重复。

Now this is code of lwipDevice for TCP server: 现在这是TCP服务器的lwipDevice代码:

long server_sock=-1;
#define FAIL 1
#define PASS 0
int CreateTcpServerSocket(long *pSock, int port)
{
    struct sockaddr_in   sin;
    int addrlen = sizeof(sin);
    int   e;
    struct linger linger;
    linger.l_linger=0;
    int i = 1;

    *pSock = socket(AF_INET, SOCK_STREAM, 0);

    if (*pSock == -1)
    {
        printf("*** createTcpSercerSocket:open sock error,port %d\n",port);
        return FAIL;
    }

    memset((char *)&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_len = sizeof(sin);
    sin.sin_addr.s_addr = htonl(INADDR_ANY);   /* wildcard IP address */
    sin.sin_port = htons(port);


    e = bind(*pSock, (struct sockaddr*)&sin, addrlen);
    if (e != 0)
    {
        printf("error %d binding tcp listen on port\n");
        closesocket(*pSock);
        *pSock = -1;
        return FAIL;
    }

    lwip_ioctl(*pSock, FIONBIO, &i); //Set Non blocking mode

    e = listen(*pSock, 2);

    if (e != 0)
    {
        pprintf("error :listen on TCP server\n");
        closesocket(*pSock);
        *pSock = -1;
        return FAIL;
    }

    return PASS;
}
void vTCPTask(void *parm)
{
    struct sockaddr client; /* for BSDish accept() call */
    int clientsize;
    long sock;

    if(CreateTcpServerSocket(&server_sock, 8000) == FAIL) //Here server created successfully
    {
        printf("Fail to create server!!!!!\n");
        server_sock=-1;
    }

    while(1)
    {
        // some code for other stuff

        sock= accept(server_sock, &client, &clientsize); //This line always fails and reurn -1

        if(sock != -1)
        {
            printf("accepted socket:\n\n");
            //...now receive data from client....
            // send some data to client
        }

        // some code for other stuff

        //sleep for 15 seconds
    }

}
int main()
{

    //...initilization of lwip stack
    //....some more code
    //...................

    xTaskCreate(vTCPTask, (signed char const *) "tcptask",
    356, NULL, 3, (xTaskHandle *)&xNotifierServiceTaskHandle);


    /* Start the scheduler */
    vTaskStartScheduler();

    return 1
}

I have checked lwip_accept function and it will return from this condition: 我检查了lwip_accept函数,它将从这个条件返回:

  if (netconn_is_nonblocking(sock->conn) && (sock->rcvevent <= 0))
  {
    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s));
    sock_set_errno(sock, EWOULDBLOCK);
    return -1;
  }

EDIT: 编辑:

I know that netconn_is_nonblocking(sock->conn) condition will always true because have set socket in non blocking mode. 我知道netconn_is_nonblocking(sock->conn)条件将始终为true,因为已将套接字设置为非阻塞模式。 But why sock->rcvevent always zero even LinuxDevice already send packet to it? 但是,为什么sock->rcvevent始终为零甚至LinuxDevice已发送数据包呢?

EDIT: 编辑:

For testing purpose have commented all other stuff code in task ( see //some code for other stuff ) then socket is successfully accepted and i try to receive the packet but now problem is it's now stuck in lwip_recvfrom function (Note: LinuxDevice continue send packets). 为了测试目的,在任务中注释了所有其他东西代码(参见//some code for other stuff )然后socket被成功接受并且我尝试接收数据包但现在问题是它现在卡在lwip_recvfrom函数中(注意: LinuxDevice继续发送数据包)。 So have further debug more and found that it stuck in function sys_arch_mbox_fetch ( function call flow:: lwip_recvfrom\\netconn_recv\\netconn_recv_data\\sys_arch_mbox_fetch ). 所以进一步调试更多,发现它停留在函数sys_arch_mbox_fetch (函数调用flow :: lwip_recvfrom\\netconn_recv\\netconn_recv_data\\sys_arch_mbox_fetch )中。

Does anyone have an idea what is wrong with it? 有谁知道它有什么问题?

You have configured the socket as non-blocking, so the accept() call will never block. 您已将套接字配置为非阻塞,因此accept()调用将永远不会阻塞。 If there is no incoming connection pending it will return the EWOULDBLOCK error code, which is what you see. 如果没有传入连接挂起,它将返回EWOULDBLOCK错误代码,这就是您所看到的。

Finally I figured out what is cause of issue. 最后我弄清楚问题的原因是什么。

In lwipopt.h file there is macro like lwipopt.h文件中有宏像

/* Non-static memory, used with DMA pool */
#ifdef __CODE_RED
#define MEM_SIZE                        (6 * 1024) 
#else
#define MEM_SIZE                        (24 * 1024)
#endif

I have defined _CODE_RED . 我已经定义了_CODE_RED So MEM_SIZE will (6 * 1024) . 所以MEM_SIZE(6 * 1024) Now when i change that memory size to (16 * 1024) then everything working fine. 现在,当我将内存大小更改为(16 * 1024)一切正常。

Now all the time connection accepted and after that i am able to send/recv tcp packets successfully. 现在一直接受连接,之后我能够成功发送/ recv tcp包。

Where do you set rcvevent ? 你在哪里设置rcvevent Your code doesn't reveal it. 您的代码没有透露它。 I suppose it's the result of recv (or read ). 我想这是recv (或read )的结果。 Reading from a non-blocking that has no available data (haven't yet received data) returns EAGAIN , which evaluates true in your rcvevent <= 0 condition. 从没有可用数据(尚未接收数据)的非阻塞中读取返回EAGAIN ,它在rcvevent <= 0条件下计算为true。 You have to manually check these specific error codes. 您必须手动检查这些特定的错误代码。

But why sock->rcvevent always zero even LinuxDevice already send packet to it? 但是为什么sock-> rcvevent总是为零,即使LinuxDevice已经发送了数据包呢?

Have you tried sending data with telnet or netcat to be sure the error is in your server and not in your client? 您是否尝试使用telnetnetcat发送数据以确保错误在您的服务器而不在您的客户端? Maybe your client is not sending to the correct destination, or something else. 也许您的客户没有发送到正确的目的地或其他东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM