64,683
社区成员
发帖
与我相关
我的任务
分享
static void RecvJsonMessage(int epfd, ServerType ServerSocket, ClientSetType &ClientSet,
int nfds, struct epoll_event* events)
{
int Ret = 0;
char RecvBuffer[256] = {0};
int connfd; //客户端网络文件描述符.
int sockfd;
struct sockaddr_in clientaddr;
socklen_t clilen;
struct epoll_event ev;
for(int i = 0; i < nfds; ++i)
{
if(events[i].data.fd == ServerSocket.ServerSocket)//如果新监测到一个SOCKET用户连接到了绑定的SOCKET端口,建立新的连接。
{
clilen = sizeof(clientaddr);
connfd = accept(ServerSocket.ServerSocket,(struct sockaddr *)&clientaddr, &clilen);
if(connfd<0)
{
if(errno == EINTR)
{
continue;
}
else
{
perror("Accept errno: connfd<0");
}
exit(-1);
}
/* Avoid TIME_WAIT */
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 0;
setsockopt(connfd, SOL_SOCKET, SO_LINGER, (const char *) &linger, sizeof(linger));
char *str = inet_ntoa(clientaddr.sin_addr);
cout<<"Accept a Connect form "<<str<<", Sockfd is "<<connfd<<endl;
//设置用于读操作的文件描述符
ev.data.fd=connfd;
//设置用于注测的读操作事件
//ev.events=EPOLLIN|EPOLLET;
ev.events= EPOLLIN | EPOLLET | EPOLLERR | EPOLLHUP | EPOLLPRI;
//注册ev
epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);
/* 初始化每个套接字描述符对应的结构体 */
ClientSet[connfd] = new ClientSocketInfo;
ClientSet[connfd]->sockfd = connfd;
ClientSet[connfd]->brace_num = 0;
ClientSet[connfd]->jsonbuffer = (char*) malloc( 1024*1024);
ClientSet[connfd]->buffersize = 1024 *1024;
memset(ClientSet[connfd]->jsonbuffer,0, 1024*1024);
}
else if(events[i].events & EPOLLIN)//如果是已经连接的用户,并且收到数据,那么进行读入。
{
if ( (sockfd = events[i].data.fd) < 0)
continue;
memset(RecvBuffer, 0, sizeof(RecvBuffer));
Ret = recv(sockfd, RecvBuffer, sizeof(RecvBuffer) - 1, 0);
if(Ret > 0)
{
/* 首先判断客户端缓冲区的大小,
如果缓冲区不够,则重新分配 */
if( ClientSet[sockfd]->buffersize
<((int)strlen(ClientSet[sockfd]->jsonbuffer) + Ret))
{
ClientSet[sockfd]->jsonbuffer =
(char*) realloc(ClientSet[sockfd]->jsonbuffer,
ClientSet[sockfd]->buffersize + 1024 *1024);
ClientSet[sockfd]->buffersize += 1024*1024;
}
strcat(ClientSet[sockfd]->jsonbuffer, RecvBuffer);
/* 检测json数据包的合法性 */
IsJsonFormatIllegal(ClientSet[sockfd]);
if(ClientSet[sockfd]->brace_num == 0)
{
/* 将接受的json数据包放入到接受队列中 */
InsertIntoJsonObj(ClientSet[sockfd], recvque);
}
else if(ClientSet[sockfd]->brace_num < 0)
{
/*出错,将将缓冲区清空 */
memset(ClientSet[sockfd]->jsonbuffer, 0,
ClientSet[sockfd]->buffersize);
}
else
{
/* 继续等待一下个数据包 */
}
}
//else if ( Ret < 0)
//{
// if (errno == ECONNRESET) {
// close(sockfd);
// events[i].data.fd = -1;
// } else
// {
// std::cout<<"readline error"<<std::endl;
// }
//}
else if (Ret <= 0)
{
cout<<"One Client Is Closed! Sockfd is "<<sockfd<<endl;
ev.data.fd=sockfd;
ev.events= EPOLLIN | EPOLLET | EPOLLERR | EPOLLHUP | EPOLLPRI;
epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,&ev);
if(close(sockfd)== -1)
{
cout<<"close error, errno: "<<errno<<endl;
}
shutdown(connfd, 2);
events[i].data.fd = -1;
free(ClientSet[sockfd]->jsonbuffer);
delete ClientSet[sockfd];
ClientSet.erase(sockfd);
}
}
else if(events[i].events & EPOLLOUT)
{
}
else
{
if ( (sockfd = events[i].data.fd) < 0)
continue;
ev.data.fd = sockfd;
epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev);
close(sockfd);
}
}
}
static void SendJsonMessage()
{
if(sendque.empty())
{
return;
}
/* 从发送队列中寻找对应的描述符 */
pthread_mutex_lock(&g_sendqueue_lock);
for(list<Value>::iterator iter = sendque.begin(); iter != sendque.end(); iter++)
{
int sockfd = (*iter)["sockfd"].asInt();
if(sockfd < 0)
{
continue;
}
string msg = (*iter)["sendcontent"].asString();
int num = send(sockfd, msg.c_str(), (int)msg.length(), 0);
if(num == (int)msg.length())
{
list<Value>::iterator tempiter = iter;
iter++;
sendque.erase(tempiter);
}
else if(num < 0)
{
DebugPrintf("Send Error: %s\n", msg.c_str());
list<Value>::iterator tempiter = iter;
iter++;
sendque.erase(tempiter);
}
}
pthread_mutex_unlock(&g_sendqueue_lock);
}
SocketCon::SocketCon()
{
}
SocketCon::~SocketCon()
{
#ifdef WIN32
closesocket(ServerSocket.ServerSocket);
WSACleanup();
#else
close((int)ServerSocket.ServerSocket);
#endif
}
int SocketCon::InitialSocketCon()
{
int opt = 1;
#ifdef WIN32
WSADATA Ws;
if(WSAStartup(MAKEWORD(2,2), &Ws) != 0)
{
cout<<"Init windows socket failed"<<GetLastError()<<endl;
}
#endif
ServerSocket.ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ServerSocket.ServerSocket < 0)
{
cout<<"Create socket failed"<<endl;
}
setsockopt(ServerSocket.ServerSocket , SOL_SOCKET, SO_REUSEADDR, (const void*)&opt, sizeof(opt));
MakeSocketNonblocking(ServerSocket);
this->epfd=epoll_create(256);
struct epoll_event ev;
ev.data.fd = ServerSocket.ServerSocket;
ev.events = EPOLLIN;
epoll_ctl(epfd,EPOLL_CTL_ADD,ServerSocket.ServerSocket,&ev);
/************************************************************/
int Ret = 0;
maxm = -1;
/* 将客户端套接字描述符集合设置为负数 */
for(int m = 0; m < FD_SETSIZE; m++)
{
client[m] = -1;
}
/* 设置非阻塞模式 */
tv.tv_usec = 0;
tv.tv_usec = 0;
/* 清除接收缓冲区 */
memset(RecvBuffer, 0, 256);
LocalAddr.sin_family = AF_INET;
#ifdef WIN32
LocalAddr.sin_addr.S_un.S_addr = inet_addr(IP_ADDRESS);
#else
LocalAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
#endif
LocalAddr.sin_port = htons(PORT);
memset(LocalAddr.sin_zero, 0x00, 8);
Ret = bind(ServerSocket.ServerSocket,
(struct sockaddr*)&LocalAddr, sizeof(LocalAddr));
if(Ret != 0)
{
cout<<"Bind socket failed"<<endl;
return -1;
}
Ret = listen(ServerSocket.ServerSocket, ListenNq);
if(Ret != 0)
{
cout<<"listen socket failed"<<endl;
return -1;
}
cout<<"server start...."<<endl;
return 0;
}
void SocketCon::RecvAndSend()
{
int nfds = 0;
//等待epoll事件的发生
nfds=epoll_wait(epfd,events,20,500);
if(nfds > 0)
{
/* 接受消息, 将json数据包放入到recvque中 */
RecvJsonMessage(this->epfd, ServerSocket, ClientSet, nfds,events);
/* 将信息发送出去 */
/*SendJsonMessage(*this, fdwrite, client, &maxm);*/
}
SendJsonMessage();
}