inserlan 发表于 2010-5-13 15:18:15

求助! RTT网络编程问题

以前我用ucos-ii+lwip, 结果BUG众多,不知如何解决,
现在改用RTT后,运行得比较稳定了,RTT确实很不错!

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

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

inserlan 发表于 2010-5-13 15:49:16

大家帮忙看看我的select程序有无问题:

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

#define MYPORT4000         //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;
        char         bufsend;       
        int         nbytes;
        int         opt;                                //for setsocket()
        int         addrlen;
        int         i,j;

        for(j = 0;j < 512; j++) {
                bufsend = '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;
}

ffxz 发表于 2010-5-13 16:12:01

>> 以前我用ucos-ii+lwip, 结果BUG众多,不知如何解决

我怎么越看越像是托

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

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

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

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

inserlan 发表于 2010-5-13 16:23:45

回复【2楼】ffxz
-----------------------------------------------------------------------

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

ffxz 发表于 2010-5-13 16:29:34

0.2.4?!

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

inserlan 发表于 2010-5-13 16:32:58

不好意思,没说清楚..
我说的'TCP读取超时' 是我的客户端读取服务器数据时发生的.
服务器作用是:一接收到客户端发过来的任何数据,就会发给客户端512个字节,
不知为何服务器send函数没有成功发送数据到客户端?

inserlan 发表于 2010-5-13 16:34:06

回复【4楼】ffxz
-----------------------------------------------------------------------

是吗?那我赶紧换~

inserlan 发表于 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);

inserlan 发表于 2010-5-13 22:12:14

哎,现在还是菜鸟的我,是纯粹的拿来主义者...
在这里感谢RTT团队,创造了这么好用的OS, 学习膜拜中..

ffxz 发表于 2010-5-13 22:16:41

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

反馈给mbbill,^-^

eworker 发表于 2010-5-13 22:19:50

学习
页: [1]
查看完整版本: 求助! RTT网络编程问题