Socket Server 简单实现.doc
文本预览下载声明
一、基本原理
有时候我们需要实现一个公共的模块,需要对多个其他的模块提供服务,最常用的方式就是实现一个Socket Server,接受客户的请求,并返回给客户结果。
这经常涉及到如果管理多个连接及如何多线程的提供服务的问题,常用的方式就是连接池和线程池,基本流程如下:
首先服务器端有一个监听线程,不断监听来自客户端的连接。
当一个客户端连接到监听线程后,便建立了一个新的连接。
监听线程将新建立的连接放入连接池进行管理,然后继续监听新来的连接。
线程池中有多个服务线程,每个线程都监听一个任务队列,一个建立的连接对应一个服务任务,当服务线程发现有新的任务的时候,便用此连接向客户端提供服务。
一个Socket Server所能够提供的连接数可配置,如果超过配置的个数则拒绝新的连接。
当服务线程完成服务的时候,客户端关闭连接,服务线程关闭连接,空闲并等待处理新的任务。
连接池的监控线程清除其中关闭的连接对象,从而可以建立新的连接。
二、对Socket的封装
Socket的调用主要包含以下的步骤:
调用比较复杂,我们首先区分两类Socket,一类是Listening Socket,一类是Connected Socket.
Listening Socket由MySocketServer负责,一旦accept,则生成一个Connected Socket,又MySocket负责。
MySocket主要实现的方法如下:
int MySocket::write(const char * buf, int length){??????? int ret = 0;??????? int left = length;??????? int index = 0;??????? while(left 0)??????? {??????????????? ret = send(m_socket, buf + index, left, 0);??????????????? if(ret == 0)??????????????????????? break;??????????????? else if(ret == -1)??????????????? {??????????????????????? break;??????????????? }??????????????? left -= ret;??????????????? index += ret;??????? }??????? if(left 0)??????????????? return -1;??????? return 0;} int MySocket::read(char * buf, int length){??????? int ret = 0;??????? int left = length;??????? int index = 0;??????? while(left 0)??????? {??????????????? ret = recv(m_socket, buf + index, left, 0);??????????????? if(ret == 0)??????????????????????? break;??????????????? else if(ret == -1)??????????????????????? return -1;??????????????? left -= ret;??????????????? index += ret;??????? }
??????? return index;} int MySocket::status(){??????? int status;??????? int ret;??????? fd_set checkset;??????? struct timeval timeout;
??????? FD_ZERO(checkset);??????? FD_SET(m_socket, checkset);
??????? timeout.tv_sec = 10;??????? timeout.tv_usec = 0;
??????? status = select((int)m_socket + 1, checkset, 0, 0, timeout);??????? if(status 0)??????????????? ret = -1;??????? else if(status == 0)??????????????? ret = 0;??????? else?????????????
显示全部