`
nkadun
  • 浏览: 54133 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

epoll + lua 简单游戏服务器(四)

 
阅读更多
/**处理请求数据,调用lua处理*/
void read_fd(int fd, lua_State *L)
{
	//已超时移除
	if(fds[fd] < 0)
		return;

	char buf[READ_SIZE];
	int ret, idx, done;
	client_data *client;
        
        //得到连接信息
	idx = fds[fd];
	client = clients[idx];

        //已读取的字节数
	done = client->read_len;
	ret = read(fd, buf, READ_SIZE);
	//连接关闭
	if(ret == 0 || (ret < 0 && ret != EAGAIN))
		remove_fd(fd, L);
	else
	{
		//完全读取
		do
		{
			//消息过长
			done += ret;
			if(done >= READ_SIZE)
			{
				remove_fd(fd, L);
				return;
			}
			memcpy(client->read + client->read_len, buf, ret);
			client->read_len = done;
		}
		while((ret = read(fd, buf, READ_SIZE)) > 0);

		//处理消息头,前4字节表示长度
		if(client->data_len == 0 && client->read_len >= 4)
		{
			int i;
			for(i = 0; i < 4; i++)
				client->data_len = (client->data_len << 8) | client->read[i];
		}

		//消息完整 TODO 客户端粘包处理
		if(client->data_len + 4 == client->read_len)
		{
			client->read[client->read_len] = '\0';

                        //调用lua处理请求
			lua_State *Lx = lua_newthread(L);
			lua_getglobal(Lx, F_ONREAD);  //lua里onread函数
			lua_pushinteger(Lx, fd);
			lua_pushstring(Lx, client->read + 4);
			ret = lua_pcall(Lx, 2, LUA_MULTRET, 0);
			if(ret != 0)
				fprintf(stderr, "%s\n", lua_tostring(Lx, -1));
			lua_settop(L, 0);
			//处理完成
			client->data_len = client->read_len = 0;
			//重置最后访问时间
			client->last = now();
		}
	}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics