rt_thread 中tcp server,在lwip_accept()函数前调用lwip_select()函数,然后客户端连上去以后,select()无法检测到事件的变化

102 views
Skip to first unread message

jason shi

unread,
Jul 3, 2014, 9:33:10 PM7/3/14
to rt-threa...@googlegroups.com
最近在看rt_thread lwip,自己写了一个小demo,发现了这个问题:

lwip_accept()函数前调用lwip_select()函数, 用lwip 网络测试工具   NetAssist.exe 作为客户端连上去以后,服务端没有任何响应。不知道是怎么回事?  下面是我的代码:

------------

void tcpserv(void *parameter)
{
struct sockaddr_in server_addr, client_addr;
int listenfd = -1, confd = -1, opt = 1;
int ret = -1;
int ndfs;
struct timeval timeout;
fd_set allset;
fd_set readset;
if( (listenfd = lwip_socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
rt_kprintf("create socket faild!\n\r");
return ;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero));
if(lwip_bind(listenfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
{
rt_kprintf("bind faild!\n\r");
lwip_close(listenfd);
return ;
}
if(listen(listenfd, BACKLOG) < 0)
{
rt_kprintf("listen faild !\n\r");
lwip_close(listenfd);
return ;
}
ndfs = listenfd + 1;

FD_ZERO(&allset);
FD_ZERO(&readset);
FD_SET(listenfd, &readset);
while(1)
{
timeout.tv_sec = 1;
timeout.tv_usec = 0;
readset = allset;
ret = lwip_select(ndfs, &readset, NULL, 0, &timeout);
if(ret < 0) 
{
rt_kprintf("select error!\n\r");
lwip_close(listenfd);
return ;
}else if(ret == 0)
{
rt_kprintf("select..........\n\r");
continue ;
}else
{
rt_kprintf("client connect ----->\n\r");
}
}
}

--------------------------------

有人遇到过这个问题吗?  谢谢! THX!

Ming Bai

unread,
Jul 3, 2014, 9:44:23 PM7/3/14
to rt-thread用户组
while(1)
{
timeout.tv_sec = 1;
timeout.tv_usec = 0;
readset = allset;
ret = lwip_select(ndfs, &readset, NULL, 0, &timeout);

--
You received this message because you are subscribed to the Google Groups "rt-thread用户组" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rt-thread-cnus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

jason shi

unread,
Jul 3, 2014, 11:14:36 PM7/3/14
to rt-threa...@googlegroups.com
谢谢 Ming,
现在我按照你的提示,将上面的代码修改为这样:
---
ndfs = listenfd + 1;

FD_ZERO(&allset);
FD_ZERO(&readset);
FD_SET(listenfd, &readset);
while(1)
{
timeout.tv_sec = 1;
timeout.tv_usec = 0;
// readset = allset;
ret = lwip_select(ndfs, &readset, NULL, 0, &timeout);
if(ret < 0) 
{
rt_kprintf("select error!\n\r");
lwip_close(listenfd);
return ;
}else if(ret == 0)
{
rt_kprintf("select..........\n\r");
continue ;
}else
{
rt_kprintf("client connect ----->\n\r");
}
}

----------------------------------------------------------------------------
然后在 lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset){} 的这里加了一行打印:
rt_kprintf("hello I/m here------------------->\n\r");
------------------------------------------------------------------------------

static int
lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)
{
  int i, nready = 0;
  fd_set lreadset, lwriteset, lexceptset;
  struct lwip_socket *p_sock;
  
  FD_ZERO(&lreadset);
  FD_ZERO(&lwriteset);
  FD_ZERO(&lexceptset);
  
  /* Go through each socket in each list to count number of sockets which
  currently match */
  for(i = 0; i < maxfdp1; i++) {
    if (FD_ISSET(i, readset)) {
      /* See if netconn of this socket is ready for read */
//这里是我自己添加的 add by myself
rt_kprintf("hello I/m here------------------->\n\r");
      p_sock = get_socket(i);
      if (p_sock && (p_sock->lastdata || (p_sock->rcvevent > 0))) {
        FD_SET(i, &lreadset);
        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i));
        nready++;

//这里是我自己添加的 add by myself
        rt_kprintf(""lwip_selscan: ready for reading\n\r");

      }
    }
    if (FD_ISSET(i, writeset)) {
      /* See if netconn of this socket is ready for write */
      p_sock = get_socket(i);
      if (p_sock && p_sock->sendevent) {
        FD_SET(i, &lwriteset);
        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i));
        nready++;
      }
    }
  }
  *readset = lreadset;
  *writeset = lwriteset;
  FD_ZERO(exceptset);
  
  return nready;
}
--------------------------------------------------------------------
但是最后发现,客户端连上以后,通过串口打印,根本就不执行 rt_kprintf("hello I/m here------------------->\n\r");也就是FD_ISSET()测试失败,然后就执行下面去了。最后就导致了 select()返回为0.
===========
如果,我去掉   if (FD_ISSET(i, readset)) 这个约束条件后,程序能够执行 rt_kprintf("hello I/m here------------------->\n\r");和 rt_kprintf(""lwip_selscan: ready for reading\n\r"); 通过串口打印,我已经观察到了这两个打印。

------
像这样:
------
  for(i = 0; i < maxfdp1; i++) {
//    if (FD_ISSET(i, readset)) {
      /* See if netconn of this socket is ready for read */
rt_kprintf("hello I/m here------------------->\n\r");
      p_sock = get_socket(i);
      if (p_sock && (p_sock->lastdata || (p_sock->rcvevent > 0))) {
        FD_SET(i, &lreadset);
        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i));
        nready++;
       rt_kprintf(""lwip_selscan: ready for reading\n\r");
      }
//    }
    if (FD_ISSET(i, writeset)) {
      /* See if netconn of this socket is ready for write */
      p_sock = get_socket(i);
      if (p_sock && p_sock->sendevent) {
        FD_SET(i, &lwriteset);
        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i));
        nready++;
      }
    }
  }
----------

由于MDK没找到 FD_ISSET()的实现,不知道为什么无法检测到呢

THX !


--
You received this message because you are subscribed to a topic in the Google Groups "rt-thread用户组" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rt-thread-cnusers/-Jla_auV0Dk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rt-thread-cnus...@googlegroups.com.

Ming Bai

unread,
Jul 3, 2014, 11:27:53 PM7/3/14
to rt-thread用户组
这些都是socket编程的问题,不一定要在lwip上做这种试验,先在PC上练练呗

jason shi

unread,
Jul 4, 2014, 12:34:28 AM7/4/14
to rt-threa...@googlegroups.com
谢谢!  

jason shi

unread,
Aug 25, 2014, 5:18:42 AM8/25/14
to rt-threa...@googlegroups.com
谢谢各位大侠,确实是自己没搞清楚  select()的性质: 程序每执行一次select(),就会把里面的某些参数重置一次,我已经写了笔记了,供有需要的新人查看吧,链接地址:

http://www.cnblogs.com/chineseboy/p/3915723.html

在 2014年7月4日星期五UTC+8上午9时33分10秒,jason shi写道:
Reply all
Reply to author
Forward
0 new messages