Android服务端本地窗口FramebufferNativeWindow

Android窗口系统

我们知道Android系统采用OpenGL来绘制3D图形,OpenGL ES提供了本地窗口(NativeWindow)的概念,无论是在Android平台中还是其他平台中,只要实现OpenGL ES中的本地窗口定义的接口,就可以利用OpenGL ES来绘制图形。由于Android系统所有服务都建立在C/S模式下,因此Android系统在实现OpenGL ES的本地窗口时仍然包括两种本地窗口,服务进程端的本地窗口定义为FramebufferNativeWindow,该本地窗口直接由 SurfaceFlinger管理。在应用程序进程端定义的本地创建为SurfaceTextureClient。在Android系统中,它们之间为一 对多的关系,如下图所示:

每个应用程序App可以有多个窗口,即多个Surface,每个Surface所需的图形缓冲区由SurfaceFlinger进程中的
BufferQueue对象负责管理,图形缓冲区个数最多可以有32个,每个图形缓冲区用GraphicBuffer来定义,应用程序在图形绘制前,请求
SurfaceFlinger进程中的BufferQueue对象在内存中分配一块图形缓冲区,应用程序完成图形绘制后,由SurfaceFlinger
将多个应用程序需要显示的Surface进行图形混合,混合后的图形窗口使用FramebufferNativeWindow来描述,同时将混合后的图形
数据拷贝到Framebuffer的后台缓冲区中,等待渲染到显示屏上。以下就是Android的窗口系统设计模型:

FramebufferNativeWindow本地窗口所需的图形缓冲区直接从Framebuffer中分配,而Surface本地窗口所需的图
形缓冲区则是从内存中分配,无论是从Framebuffer中分配还是从内存中分配,图形缓冲区的分配工作都是由Gralloc硬件抽象层完成,在Android图形显示之硬件抽象层Gralloc中详细分析了Gralloc模块,而Android图形缓冲区分配过程源码分析则分析了图形缓冲区的分配过程。SurfaceFlinger收集所有应用程序的显示需求,然后对应用程序所需显示的图形做图像混合操作,然后输出到自己的FramebufferNativeWindow本地窗口上。为了使用OpenGL
ES绘制图形窗口,必须实现OpenGL ES定义的本地窗口协议NativeWindow。

[cpp] view plaincopy

  1. EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
  2. NativeWindowType window,
  3. const EGLint *attrib_list)

函数eglCreateWindowSurface是OpenGL ES提供用于创建窗口的函数接口,参数window的类型为NativeWindowType,定义如下:

frameworks\native\opengl\include\EGL\eglplatform.h

[cpp] view plaincopy

  1. typedef EGLNativeWindowType  NativeWindowType;
  2. #if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
  3. typedef HWND    EGLNativeWindowType;
  4. #elif defined(__WINSCW__) || defined(__SYMBIAN32__)  /* Symbian */
  5. typedef void *EGLNativeWindowType;
  6. #elif defined(__ANDROID__) || defined(ANDROID)
  7. typedef struct ANativeWindow*           EGLNativeWindowType;
  8. #elif defined(__unix__)
  9. typedef Window   EGLNativeWindowType;
  10. #else
  11. #error "Platform not recognized"
  12. #endif

NativeWindowType
定义为EGLNativeWindowType类型,而该类型在不同的平台中有不同的定义,这是因为OpenGL
ES是一个跨平台的图形绘制库,对于Android系统来说,其定义为ANativeWindow指针类型,而ANativeWindow的定义如下:

[cpp] view plaincopy

  1. struct ANativeWindow
  2. {
  3. #ifdef __cplusplus
  4. ANativeWindow(): flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
  5. {
  6. common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
  7. common.version = sizeof(ANativeWindow);
  8. memset(common.reserved, 0, sizeof(common.reserved));
  9. }
  10. void incStrong(const void* id) const {
  11. common.incRef(const_cast<android_native_base_t*>(&common));
  12. }
  13. void decStrong(const void* id) const {
  14. common.decRef(const_cast<android_native_base_t*>(&common));
  15. }
  16. #endif
  17. struct android_native_base_t common;
  18. const uint32_t flags;//用于描述该Surface的一些属性
  19. const int   minSwapInterval;//最小交换间隔时间
  20. const int   maxSwapInterval;//最大交换间隔时间
  21. const float xdpi;//水平方向的密度
  22. const float ydpi;//垂直方向的密度
  23. intptr_t    oem[4];//为OEM预留
  24. //设置交换间隔时间
  25. int     (*setSwapInterval)(struct ANativeWindow* window,int interval);
  26. //申请一个图形缓冲区buffer
  27. int     (*dequeueBuffer)(struct ANativeWindow* window,struct ANativeWindowBuffer** buffer);
  28. //锁定图形缓冲区
  29. int     (*lockBuffer)(struct ANativeWindow* window,struct ANativeWindowBuffer* buffer);
  30. //buffer渲染完成后,它调用这个接口来unlock和post buffer
  31. int     (*queueBuffer)(struct ANativeWindow* window,struct ANativeWindowBuffer* buffer);
  32. //向本地窗口查询相关信息
  33. int     (*query)(const struct ANativeWindow* window,int what, int* value);
  34. //执行本地窗口支持的各种操作
  35. int     (*perform)(struct ANativeWindow* window,int operation, ... );
  36. //取消一个已经dequeued的buffer
  37. int     (*cancelBuffer)(struct ANativeWindow* window,struct ANativeWindowBuffer* buffer);
  38. //预留
  39. void* reserved_proc[2];
  40. }android_native_window_t;

当使用C++编译器是,为ANativeWindow定义了相应的构造函数,在OpenGL ES下的Android本地窗口系统的类关系图如下:

从上图可以看出,Surface和FramebufferNativeWindow都继承于ANativeWindow,因此也就继承了
OpenGL ES下的本地窗口定义的相关协议:ANativeWindow中定义的相关接口。下面分别对这两种类型的本地窗口进行深入分析。

FramebufferNativeWindow

前面已经介绍了FramebufferNativeWindow是SurfaceFlinger服务进程维护的本地窗口,用于描述经过图形混合
后的,即将渲染显示的图形窗口。FramebufferNativeWindow不仅实现了从ANativeWindow中继承下来的接口,自己还定义了
一些额外属性:

[cpp] view plaincopy

  1. class FramebufferNativeWindow
  2. : public ANativeObjectBase<
  3. ANativeWindow,
  4. FramebufferNativeWindow,
  5. LightRefBase<FramebufferNativeWindow> >
  6. {
  7. framebuffer_device_t* fbDev; //描述Framebuffer设备
  8. alloc_device_t* grDev; //描述gpu设备
  9. sp<NativeBuffer> buffers[NUM_FRAME_BUFFERS];//定义2个图形缓冲区
  10. sp<NativeBuffer> front; //前台图形缓冲区,即正在渲染的图形缓冲区
  11. mutable Mutex mutex;
  12. Condition mCondition;
  13. int32_t mNumBuffers; //图形缓冲区个数
  14. int32_t mNumFreeBuffers; //可以使用的图形缓冲区个数
  15. int32_t mBufferHead; //
  16. int32_t mCurrentBufferIndex;//当前图形缓冲区的索引
  17. bool mUpdateOnDemand;
  18. };

接下来看看FramebufferNativeWindow对象的构造过程:

[cpp] view plaincopy

  1. FramebufferNativeWindow::FramebufferNativeWindow() : BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false)
  2. {
  3. hw_module_t const* module;
  4. //加载gralloc模块
  5. if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
  6. int stride;
  7. int err;
  8. int i;
  9. //打开fb设备
  10. err = framebuffer_open(module, &fbDev);
  11. ALOGE_IF(err, "couldn‘t open framebuffer HAL (%s)", strerror(-err));
  12. //打开gpu设备
  13. err = gralloc_open(module, &grDev);
  14. ALOGE_IF(err, "couldn‘t open gralloc HAL (%s)", strerror(-err));
  15. //设备打开失败,返回
  16. if (!fbDev || !grDev)
  17. return;
  18. mUpdateOnDemand = (fbDev->setUpdateRect != 0);
  19. // 初始化变量值
  20. mNumBuffers = NUM_FRAME_BUFFERS;//2
  21. mNumFreeBuffers = NUM_FRAME_BUFFERS;//2
  22. mBufferHead = mNumBuffers-1;//1
  23. #ifdef FRAMEBUFFER_FORCE_FORMAT
  24. *((uint32_t *)&fbDev->format) = FRAMEBUFFER_FORCE_FORMAT;
  25. #endif
  26. //创建2个NativeBuffer
  27. for (i = 0; i < mNumBuffers; i++)
  28. {
  29. buffers[i] = new NativeBuffer(fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);
  30. }
  31. //为NativeBuffer分配缓冲区
  32. for (i = 0; i < mNumBuffers; i++)
  33. {
  34. err = grDev->alloc(grDev,fbDev->width, fbDev->height, fbDev->format,GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride);
  35. ALOGE_IF(err, "fb buffer %d allocation failed w=%d, h=%d, err=%s",i, fbDev->width, fbDev->height, strerror(-err));
  36. if (err)
  37. {
  38. mNumBuffers = i;
  39. mNumFreeBuffers = i;
  40. mBufferHead = mNumBuffers-1;
  41. break;
  42. }
  43. }
  44. //使用Framebuffer的设备描述符来初始化本地窗口ANativeWindow的相关属性
  45. const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags;
  46. const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;
  47. const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;
  48. const_cast<int&>(ANativeWindow::minSwapInterval) = fbDev->minSwapInterval;
  49. const_cast<int&>(ANativeWindow::maxSwapInterval) = fbDev->maxSwapInterval;
  50. } else {
  51. ALOGE("Couldn‘t get gralloc module");
  52. }
  53. //为本地窗口ANativeWindow设置回调接口函数
  54. ANativeWindow::setSwapInterval = setSwapInterval;
  55. ANativeWindow::dequeueBuffer = dequeueBuffer;
  56. ANativeWindow::lockBuffer = lockBuffer;
  57. ANativeWindow::queueBuffer = queueBuffer;
  58. ANativeWindow::query = query;
  59. ANativeWindow::perform = perform;
  60. }

函数首先加载Gralloc模块,关于硬件抽象层模块的加载过程,在Android硬件抽象Hardware库加载过程源码分析
经有详细的介绍了。当成功加载Gralloc模块后,依次打开Gralloc模块中定义的Framebuffer设备及gpu设备,我们知道
Gralloc模块中定义的Framebuffer设备用于将已经准备好了的图形缓冲区渲染到帧缓冲区中,而定义的gpu设备用于分配一块图形缓冲区,并
且将这块图形缓冲区映射到应用程序的地址空间。关于Framebuffer设备和gpu设备的打开过程请参阅Android图形显示之硬件抽象层Gralloc
打开fb和gpu设备后,将这两种设备描述符分别保存到FramebufferNativeWindow的成员变量fbDev和grDev中。接着创建了
两个NativeBuffer对象,并从Framebuffer帧缓冲区中分配了两块图形缓冲区。Android系统为定义的两种本地窗口分别定义了相应
的图形缓冲区buffer的描述符,对于FramebufferNativeWindow本地窗口来说,为其定义的图形缓冲区描述符为
NativeBuffer,而对于应用程序端的本地窗口Surface,为其定义的图形缓冲区描述符为GraphicBuffer,它们之间的类关系图如
下:

从上面的类继承图中可以看出,无论是NativeBuffer还是GraphicBuffer,它们都继承于
ANativeWindowBuffer,ANativeWindowBuffer用于描述一块图形缓冲区buffer的属性信息,比如图形的宽,高,图
像格式及该buffer的句柄等等信息。

[cpp] view plaincopy

  1. typedef struct ANativeWindowBuffer
  2. {
  3. //针对C++编译器定义构造函数
  4. #ifdef __cplusplus
  5. ANativeWindowBuffer() {
  6. common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
  7. common.version = sizeof(ANativeWindowBuffer);
  8. memset(common.reserved, 0, sizeof(common.reserved));
  9. }
  10. void incStrong(const void* id) const {
  11. common.incRef(const_cast<android_native_base_t*>(&common));
  12. }
  13. void decStrong(const void* id) const {
  14. common.decRef(const_cast<android_native_base_t*>(&common));
  15. }
  16. #endif
  17. struct android_native_base_t common;//描述EGL版本信息
  18. int width; //图像宽度
  19. int height; //图像高度
  20. int stride; //
  21. int format; //图像格式
  22. int usage; //该buffer的用途
  23. void* reserved[2]; //保留
  24. buffer_handle_t handle; //该buffer的句柄信息
  25. void* reserved_proc[8];
  26. } android_native_buffer_t;

接着为创建的2个NativeBuffer分配空间,使用Gralloc模块中的gpu来完成空间的分配过程,同时指定标志位为GRALLOC_USAGE_HW_FB,表示从系统帧缓冲区Framebuffer中分配。

[cpp] view plaincopy

  1. err = grDev->alloc(grDev,fbDev->width, fbDev->height, fbDev->format,GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride);

关于图形缓冲区的完整分配过程请阅读Android图形缓冲区分配过程源码分析
FramebufferNativeWindow完成图形缓冲区的分配后,还需初始化从ANativeWindow中继承而来的本地窗口定义的相关接口,
即FramebufferNativeWindow实现ANativeWindow本地窗口协议。从FramebufferNativeWindow的构
造函数中,我们知道,FramebufferNativeWindow从Framebuffer中分配了2个缓冲区,说明
FramebufferNativeWindow使用了双缓冲技术,使用双缓冲技术的优点是什么呢?假设我们需要绘制这样一个画面,包括两个三角形和三个
圆形,最终结果如下图所示:

在只有一个buffer的情况下,我们是直接以屏幕为画板来实时做画的,假设图中的每一个三角形或圆形都需要0.5秒为例,那么总计耗时应该是0.5*5=2.5秒,图形绘制过程如下:

对于用户来说,他将看到一个不断刷新的画面。对于图像刷新很频繁的情况,用户的体验就会更差。出现这种现象的原因就是程序直接以屏幕为绘图板,把还
没有准备就绪的图像直接呈现给了用户。换句话说,如果将整幅图绘制完成以后再刷新到屏幕上,那么对于用户来说,他在任何时候看到的都是完整的图像。采用两
个缓冲区绘制图形的情况如下:

既然FramebufferNativeWindow创建了两块图形缓冲区,那它是如何维护这两块图形缓冲区的呢?接下来就介绍图形缓冲区的申请过程:

[cpp] view plaincopy

  1. int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,
  2. ANativeWindowBuffer** buffer)
  3. {
  4. FramebufferNativeWindow* self = getSelf(window);
  5. Mutex::Autolock _l(self->mutex);
  6. //从FramebufferNativeWindow对象中取出fb设备描述符,在构造FramebufferNativeWindow对象时,已经打开了fb设备
  7. framebuffer_device_t* fb = self->fbDev;
  8. //计算当前申请的图形缓冲区在buffers数组中的索引,同时将下一个申请的buffer的索引保存到mBufferHead中
  9. int index = self->mBufferHead++;
  10. //如果申请的下一个buffer的索引大于或等于buffer总数,则将下一个申请的buffer索引设置为0,这样就实现了对buffer数组的循环管理
  11. if (self->mBufferHead >= self->mNumBuffers)
  12. self->mBufferHead = 0;
  13. //如果当前没有空闲的buffer,即mNumFreeBuffers= 0,则线程睡眠等待buffer的释放
  14. while (!self->mNumFreeBuffers) {
  15. self->mCondition.wait(self->mutex);
  16. }
  17. //存在了空闲buffer,线程被唤醒继续执行,由于此时要申请一块buffer,因此空闲buffer的个数又需要减1
  18. self->mNumFreeBuffers--;
  19. //保存当前申请的buffer在缓冲区数组中的索引位置
  20. self->mCurrentBufferIndex = index;
  21. //得到buffer数组中的NativeBuffer对象指针
  22. *buffer = self->buffers[index].get();
  23. return 0;
  24. }

dequeueBuffer
函数就是从FramebufferNativeWindow创建的包含2个图形缓冲区的缓冲区队列buffers中取出一块空闲可用的图形buffer,
如果当前缓冲区队列中没有空闲的buffer,则当前申请buffer线程阻塞等待,等待其他线程释放图形缓冲区。mNumFreeBuffers用来描
述可用的空闲图形buffer个数,index记录当前申请buffer在图形缓冲区队列中的索引位置,mBufferHead指向下一次申请的图形
buffer的位置,由于我们是循环利用两个缓冲区的,所以如果这个变量的值超过mNumBuffers,就需要置0。也就是说mBufferHead的
值永远只能是0或者1。

上图描述了图形绘制的整个过程,SurfaceFlinger首先从FramebufferNativeWindow中申请出列一块图形
buffer,然后将系统中的各个Surface的GraphicBuffer进行图形混合,将混合后的图形保存到申请所得的图形buffer中,接着将
该buffer放回FramebufferNativeWindow的图形缓冲区队列中,最后将该buffer渲染到显示屏幕上。接下来介绍图形
buffer如列过程:

[cpp] view plaincopy

  1. int FramebufferNativeWindow::queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer)
  2. {
  3. FramebufferNativeWindow* self = getSelf(window);
  4. Mutex::Autolock _l(self->mutex);
  5. //从FramebufferNativeWindow对象中取出fb设备描述符,在构造FramebufferNativeWindow对象时,已经打开了fb设备
  6. framebuffer_device_t* fb = self->fbDev;
  7. //从NativeBuffer对象中取出buffer_handle_t
  8. buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle;
  9. const int index = self->mCurrentBufferIndex;
  10. //调用framebuffer_device_t中注册的post函数将已绘制好的buffer渲染到Framebuffer中。
  11. int res = fb->post(fb, handle);
  12. //将当前NativeBuffer保存为前台buffer
  13. self->front = static_cast<NativeBuffer*>(buffer);
  14. //由于当前NativeBuffer已经渲染完成,因此将当前buffer入列,从而可以被申请
  15. self->mNumFreeBuffers++;
  16. //唤醒图形buffer申请出列线程,表示已有空闲buffer可以被申请
  17. self->mCondition.broadcast();
  18. return res;
  19. }

这里将调用fb设备的post方法将buffer渲染到屏幕上,然后修改空闲buffer个数,最后唤醒正在申请图形buffer出列,却因无空闲buffer而睡眠的线程。

[cpp] view plaincopy

  1. static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
  2. {
  3. //校验buffer_handle_t
  4. if (private_handle_t::validate(buffer) < 0)
  5. return -EINVAL;
  6. //将framebuffer_device_t强制转换为fb_context_t指针
  7. fb_context_t* ctx = (fb_context_t*)dev;
  8. //将buffer_handle_t强制转换为private_handle_t指针
  9. private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer);
  10. //通过fb_context_t设备描述符找到对应的硬件抽象设备hw_device_t,在根据hw_device_t找到对应的硬件抽象模块hw_moudle_t,最后强制转换为private_module_t指针
  11. private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
  12. //如果当前buffer是从Framebuffer中分配的缓冲区
  13. if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
  14. const size_t offset = hnd->base - m->framebuffer->base;
  15. m->info.activate = FB_ACTIVATE_VBL;
  16. m->info.yoffset = offset / m->finfo.line_length;
  17. if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
  18. ALOGE("FBIOPUT_VSCREENINFO failed");
  19. m->base.unlock(&m->base, buffer);
  20. return -errno;
  21. }
  22. m->currentBuffer = buffer;
  23. } else {
  24. // If we can‘t do the page_flip, just copy the buffer to the front
  25. // FIXME: use copybit HAL instead of memcpy
  26. void* fb_vaddr;
  27. void* buffer_vaddr;
  28. m->base.lock(&m->base, m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY, 0, 0, m->info.xres, m->info.yres,&fb_vaddr);
  29. m->base.lock(&m->base, buffer, GRALLOC_USAGE_SW_READ_RARELY, 0, 0, m->info.xres, m->info.yres,&buffer_vaddr);
  30. memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
  31. m->base.unlock(&m->base, buffer);
  32. m->base.unlock(&m->base, m->framebuffer);
  33. }
  34. return 0;
  35. }

最后通过FBIOPUT_VSCREENINFO命令进入Framebuffer驱动,将图形渲染显示。

时间: 2024-10-05 15:58:25

Android服务端本地窗口FramebufferNativeWindow的相关文章

erlang-百度云推送Android服务端功能实现-erlang

百度云推送官方地址http://developer.baidu.com/wiki/index.php?title=docs/cplat/push 简单的介绍下原理: 百度云推送支持IOS和Android的云推送.Android支持的还不错,但是IOS一般很难调通.百度云对于IOS的推送来说,他只是做了一个中间的代理,为用户提供接口,优点是使用百度云推送,Android和IOS可以统一管理:缺点是:调通不容易,用户的IOS证书需要上传验证,会直接暴露给第三方,并且IOS的apns支持用户自己构建p

使用Zabbix服务端本地邮箱账号发送报警邮件的部署记录

邮件报警有两种情况:1)Zabbix服务端只是单纯的发送报警邮件到指定邮箱,发送报警邮件的这个邮箱账号是Zabbix服务端的本地邮箱账号(例如:[email protected]),只能发送,不能接收外部邮件.2)使用一个可以在互联网上正常收发邮件的邮箱账号(例如:[email protected]),通过在Zabbix服务端中设置,使其能够发送报警邮件到指定邮箱.上面第2中使用外部邮箱发送报警邮件之前已经介绍了:分布式监控系统Zabbix-3.0.3-完整安装记录(5)-邮件报警部署.下面说下

Android服务端开发1-使用Eclipse搭建Java Web服务端

本篇博客介绍如何使用Eclipse来创建一个Java Web程序,为后面讲通过Android客户端跟服务端进行交互打下基础,关于服务端可以选用的程序很多,主流的搭配是Android客户端+PHP服务端,我们也可以使用Android客户端+Java EE服务端这样的搭配,就看公司是以哪种方式提供了. 创建一个Java Web程序,没有特别复杂的流程,我们先准备一下原材料: 1. Eclipse(注:这个不是ADT Bundle,最好到官网下载针对开发Java EE的IDE,如果可以的话,选中MyE

开发android服务端的开发环境配置

服务器端开发的简单示例: 1.  MyEclipse的安装与使用 2.  Tomacat的安装与使用 3.  MySql的安装与MySql的可视化开发工具SQLyog的安装与使用 最近自己开发了一款android端的app,考虑到UI界面都既然已经做完了,那就再继续学习服务端的开发,希冀能自己独立做完一款应用出来.这里同步将自己搭建服务器的各种开发工具,破解及汉化的步骤写出来,供大家交流. 服务端的开发考虑过使用php或者j2ee,当然两者我的了解都不甚很多,php可能更倾向于作为网站后台,而j

【急】c#服务器用套接字与android服务端互通训,要双向的,我自己写了一个,不成功,求例子,求指导,急啊

============问题描述============ c#服务端:  //创建监听端口.....  private void StartListening()         {               //创建IPEndPoint             IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.16.41.120"), 8897);               //创建Socket实例           s

Android服务端的设计

1.创建自己的MyServletContextListener.java: package yybwb; import java.net.ServerSocket; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class MyServletContextListener implements ServletContextListener { //这里使该

Android服务端查询数据库操作

============问题描述============ 实现用户登录功能,在手机客户端拿到用户的名称(username)和密码(password),然后在服务器端进行查询该用户,查询语句应该怎么写?我是这么写的; // 创建数据库的链接,查询该用户 JDBConnection sqlConn = new JDBConnection(); sqlConn.executeQuery("select name,password from user_test where name = '"

[PHP]AES加密----PHP服务端和Android客户端

本文采取128位AES-CBC模式加密和解密 1.首先对服务端安装mcrypt: sudo apt-get install php5-mcrypt php5-dev sudo php5enmod mcrypt sudo service apache2 restart 2.PHP服务端AES加密类代码 class MCrypt { private $iv = 'fedcba9876543210'; //初始化向量iv public $key;//AES加密的密钥key //将密钥$key传进本类

linux epoll机制对TCP 客户端和服务端的监听C代码通用框架实现

1 TCP简介 tcp是一种基于流的应用层协议,其"可靠的数据传输"实现的原理就是,"拥塞控制"的滑动窗口机制,该机制包含的算法主要有"慢启动","拥塞避免","快速重传". 2 TCP socket建立和epoll监听实现 数据结构设计 linux环境下,应用层TCP消息体定义如下: typedef struct TcpMsg_s { TcpMsgHeader head; void* msg; }TcpM