linux聊天服务器开发

由于工作需要,最近开发了这么样的一个服务器端程序。严格意义上面来讲,这个程序并不是平常聊天的服务器程序,它是一个游戏系统中的广播服务器处理程序。不过只需要稍微做一些修改的话,他就可以成为一个聊天的服务器。

首先简单地介绍一下功能(希望我们的程序员不要觉得麻烦),游戏已经上线了,根据设想,我们还想做一个广播系统,即游戏里面的用户发生了一些事件,我们在php的代码中,将这些事件经过后端的服务器发到前端的flash页面上,让所有的用户都知道这样一件事情。

这个就是简单的程序运行示意图,linux服务器主要处理的就是从php程序中接受数据,让后将这些数据推送到前台的页面上去。

这样的一个系统,我采用的是socket来实现它,今天我们不介绍php是如何处理socket的,前面已经有相关的文件介绍,另外,对于数据传输使用的协议,这里也不做介绍,这个东西只要我们对服务器和php程序做统一的规定就好了。我们的重点是总结一下这个广播后台的实现过程:

 

我们简单地看看使用socket服务器需要做那些处理:

1。加载socket 协议,

2。创建一个socket对象,

3。将该socket bind到一个端口,

4。监听该端口的相应(使用listener),

5。接受客户端的socket,

6。建立数据库传输。

 

大部分socket编程都会使用上面的结构,我们这里也是,使用的tcp协议。对于我们的程序,这里有个特殊的要求,我们不是面对一对一的数据传输,我们只是从一个地方接受数据,但是我们要将这个数据推送到前面的很多客户端上面去,所以我们的客户端连接讲是一个数组。在我的程序里面我使用这样的结构

typedef struct CLIENT {
    int fd;
    struct sockaddr_in addr;   
}CLIENT;

 CLIENT client[FD_SETSIZE]; //后面的FD_SETSIZE设置为1024

while (1)
{

  confd =accept(slisten,  (struct sockaddr*)&addr,&len)) == -1;

  if(confd)

  {

    for (i=0; i<FD_SETSIZE; i++)

    {

      if(client[i].fd<0)

      {

        client[i].fd = confd;

        client[i].addr = addr;

      }

    }

  }

}

上面的代码就是将这样的一个client填满,如果有些客户端断掉了,我们再使用新来的连接将其补上。

 

上面说了,这个程序还要接受php程序的数据,那么就必须使用到recv 和send函数,但是我们知道,这些函数是阻塞I/O,如果没有数据进来的话,程序就会停留在这个地方,这样需要推送的数据自然发送不了(大家可以自己动手实现一下,)。要解决这样一个问题,那就必须使用非阻塞式编程啦。

在这里我使用了select 函数,具体的使用详细地介绍,大家可以上网去查查:

fd_set 是select 的一个基本结构,这里我们定义

fd_set allset, rset;

 FD_ZERO(&allset);     //初始化     
 FD_SET(slisten, &allset); //将服务器的socket放到select中 
 maxfd = slisten;  

nready = select(maxfd + 1, &rset, NULL, NULL, &tv); //注意第一个参数一定要加一, 这个函数很重要,在使用的使用查清楚

我们会根据这个nready的值来做不同的处理:

if(nready==0) //超时

else if(nready < 0) //出错

else

{

  //说明有数据传输

 //使用FD_ISSET来判断是哪一个有反映,例如有新的接口,接受数据等等

}

 

这里再提一个问题,刚才讲了一个程序只能处理1024个的连接,那如果用户的数目大于1024, 需要怎么处理了?

 

posted @ 2010-08-01 16:13  库从志  阅读(1375)  评论(0编辑  收藏  举报