搜索
bottom↓
回复: 10

求助! RTT网络编程问题

[复制链接]

出0入0汤圆

发表于 2010-5-13 15:18:15 | 显示全部楼层 |阅读模式
以前我用ucos-ii+lwip, 结果BUG众多,不知如何解决,
现在改用RTT后,运行得比较稳定了,RTT确实很不错!

现在我要实现服务器能被 多客户端同时访问, 我目前用的方法是BSD SOCKET的select机制,但是只要其中一个操作失败(现在是经常TCP读取超时)
便导致整个网络进程堵死,只有空闲程序在运行了...

我想请教下RTT能不能像LINUX那样fork出子进程,来实现同时处理多个客户端连接?
本人刚接触RTT,还望高手指点一二..

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2010-5-13 15:49:16 | 显示全部楼层
大家帮忙看看我的select程序有无问题:

#include <lwip/sockets.h> /* 使用BSD Socket接口必须包含sockets.h这个头文件*/

#define MYPORT  4000         //port we're listening on

int tcpserv(void)
{
        fd_set        master;                //master file descriptor list
        fd_set        read_fds;                //temp file descriptor list for select()
        struct sockaddr_in        myaddr;                //server address
        struct sockaddr_in        remoteaddr;        //client address
        int         fdmax;                        //maximum file descriptor number
        int         listener;                        //listening socket descriptor
        int         newfd;                        //newly accept()ed socket descriptor
        char        bufrecv[32];
        char         bufsend[512];       
        int         nbytes;
        int         opt;                                //for setsocket()
        int         addrlen;
        int         i,j;

        for(j = 0;j < 512; j++) {
                bufsend[j] = 't';
        }

        FD_ZERO(&master);        //clear the master and temp sets
        FD_ZERO(&read_fds);

        //get the listener
        listener = socket(AF_INET, SOCK_STREAM, 0);

        //set the socket
        setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));

        //bind
        myaddr.sin_family = AF_INET;
        myaddr.sin_addr.s_addr = INADDR_ANY;
        myaddr.sin_port = htons(MYPORT);
        memset(&(myaddr.sin_zero), '\0', 8);
        bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr));

        //listen
        listen(listener, 10);

        //add the listener to the master set
        FD_SET(listener, &master);

        //keep track of the biggest file descriptor
        fdmax = listener;                //so far, it's this one

        //main loop
        for( ; ; )  {
                read_fds = master;                //copy it
                select(fdmax+1, &read_fds, NULL, NULL, NULL);

                //run through the existing connections looking for data to read
                for(i = 0; i <= fdmax; i++)  {
                        if(FD_ISSET(i, &read_fds))  {                //we got one!!
                                if(i == listener)  {
                                        //handler new connections
                                        addrlen = sizeof(remoteaddr);
                                        if((newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen)) == -1)  {
                                        }  else  {
                                                FD_SET(newfd, &master);        //add to master set
                                                if(newfd > fdmax)  {                //keep track of the maximum
                                                        fdmax = newfd;
                                                }
                                        }
                                }  else  {
                                        //handle data from a client
                                        nbytes = recv(i, bufrecv, sizeof(bufrecv), 0);
                                        if(nbytes <= 0)  {
                                                //got error or connection closed by client
                                                closesocket(i);    //bye!
                                                FD_CLR(i, &master);        //remove from master set
                                        } else  {
                                                //send to client
                                                send(i, bufsend, sizeof(bufsend), 0);       
                                        }
                                }
                        }
                }
        }
        return 0;
}

出0入0汤圆

发表于 2010-5-13 16:12:01 | 显示全部楼层
>> 以前我用ucos-ii+lwip, 结果BUG众多,不知如何解决

我怎么越看越像是托

你的问题反映到你的代码上,具体是什么地方出了问题?似乎没发现有超时的地方

这个吗:nbytes = recv(i, bufrecv, sizeof(bufrecv), 0);

fork的意思是创建一个进程,而进程与线程的区别体现在进程有独立的地址空间,而线程的地址空间是共享的。RT-Thread做为实时线程来说,当然整个地址空间都是共享的,所以不可能存在fork出一个进程的情况。

但反映到工作原理上,是可以创建出新的线程来服务客户端的,这样的坏处是比较占内存。

出0入0汤圆

 楼主| 发表于 2010-5-13 16:23:45 | 显示全部楼层
回复【2楼】ffxz  
-----------------------------------------------------------------------

谢谢你的答复,
我不是托啊,
确实与我以前的UCOS-II工程比较, RTT工程代码量和内存占用都小了,而且稳定性高了.
我测试了你RTT0.2.4,echo了70多万次,除了有几个'打开TCP超时' 的错误外,没有啥异常,
不像我以前的工程,运行个几千次就发生 数据中止....

出0入0汤圆

发表于 2010-5-13 16:29:34 | 显示全部楼层
0.2.4?!

不会你现在还在用0.2.4?换0.3.0正式版,0.2.4版本的lwip select铁定出问题。

出0入0汤圆

 楼主| 发表于 2010-5-13 16:32:58 | 显示全部楼层
不好意思,没说清楚..
我说的'TCP读取超时' 是我的客户端读取服务器数据时发生的.
服务器作用是:一接收到客户端发过来的任何数据,就会发给客户端512个字节,
不知为何服务器send函数没有成功发送数据到客户端?

出0入0汤圆

 楼主| 发表于 2010-5-13 16:34:06 | 显示全部楼层
回复【4楼】ffxz  
-----------------------------------------------------------------------

是吗?那我赶紧换~

出0入0汤圆

 楼主| 发表于 2010-5-13 22:09:57 | 显示全部楼层
RTT0.3.0果然不错!

现在换成0.3.0版本后,3个客户端程序不停地访问服务器2个小时了,没有出现任何异常...明天接着测试..

值得一提的是:
我的硬件环境是AT91SAM7X256+DM9161, 用RTT0.3.0自带的网卡驱动文件会发生开机运行数秒钟后,网卡中断不响应了。 无法通信的情况!

正如ljt8015 在
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3910844&bbs_page_no=2&bbs_id=3066
中说的那样,后面我改用ljt8015所写的网卡驱动,就一切OK了!

还有就是AT91SAM7X256的EMAC有2种接口:MII和RMII  ,针对不同的接口,驱动程序会有所不同,
我觉得在网卡驱动中需要把这两种接口的驱动都写上去.

由于我用的是RMII接口,我修改了原驱动的三个地方:
sam7xether_init函数中:
       AT91C_BASE_PIOB->PIO_PPUDR = (1<<16) | (1<<15);
       改为
      AT91C_BASE_PIOB->PIO_PPUDR = 1 << 15;

       AT91C_BASE_EMAC->EMAC_USRIO= AT91C_EMAC_CLKEN;
      改为
       AT91C_BASE_EMAC->EMAC_USRIO= AT91C_EMAC_RMII | AT91C_EMAC_CLKEN;

       linksetup函数中的以下指令注释掉:
        //          tout = read_phy(PHY_REG_BMCR);
       //          tout = read_phy(PHY_REG_BMCR);
       //          tout &= ~BMCR_ISOLATE;
       //          write_phy(PHY_REG_BMCR, tout);

出0入0汤圆

 楼主| 发表于 2010-5-13 22:12:14 | 显示全部楼层
哎,现在还是菜鸟的我,是纯粹的拿来主义者...
在这里感谢RTT团队,创造了这么好用的OS, 学习膜拜中..

出0入0汤圆

发表于 2010-5-13 22:16:41 | 显示全部楼层
>> 我的硬件环境是AT91SAM7X256+DM9161, 用RTT0.3.0自带的网卡驱动文件会发生开机运行数秒钟后,网卡中断不响应了。 无法通信的情况!

反馈给mbbill,^-^

出0入0汤圆

发表于 2010-5-13 22:19:50 | 显示全部楼层
学习
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 17:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表