#include "server.h"
#include "logger/logger.h"
#define TAG "Server"
Server::Server(bool isstop, ClientNode *head, OnlineUser *uhead):
mIsStop(isstop),
mHead(head),
mUhead(uhead)
{
}
Server::~Server()
{
}
//connect
bool Server::Connected()
{
void *exit_p;
bool result = Init();
if(result)
{
if(0 != pthread_create(&mPthread, NULL, SelectThread, this))
{
LOG(TAG, "create thread error ...");
return false;
}
if(0 != pthread_join(mPthread, &exit_p))
{
LOG(TAG, "join thread error ...");
return false;
}
}
return true;
}
void Server::DisConnected()
{
}
//socket->bind->listen
bool Server::Init()
{
int result = 0;
signal(SIGPIPE, RecvSignal);
LOG(TAG, "socket ...");
mSocketfd = socket(AF_INET, SOCK_STREAM, 0);
if(mSocketfd < 0)
{
LOG(TAG, "socket error ...");
return false;
}
mSaddr.sin_family = AF_INET;
mSaddr.sin_port = htons(mConfig.port.toUShort());
mSaddr.sin_addr.s_addr = INADDR_ANY;
socklen_t on = 1;
result = setsockopt(mSocketfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if(result < 0)
{
LOG(TAG, "setsockopt error ...");
return false;
}
LOG(TAG, "bind ...");
result = bind(mSocketfd, (sockaddr *)&mSaddr, (socklen_t)sizeof(mSaddr));
if(result < 0)
{
LOG(TAG, "bind error ...");
return false;
}
LOG(TAG, "listen ...");
result = listen(mSocketfd, 20);
if(result < 0)
{
LOG(TAG, "listen error ...");
return false;
}
return true;
}
void Server::DeInit()
{
mIsStop = true;
}
//send regist/login status is successed or failed
bool Server::WriteToClient(int flag)
{
int result = 0;
result = write(mTempfd, &flag, sizeof(int));
if(result < 0)
{
LOG(TAG, "write error ...");
return false;
}
LOG(TAG, "regist/login successed ...");
return true;
}
//send userinfo to user who is login successed
bool Server::WriteToClient(const UserInfo &userinfo)
{
int result = 0;
result = write(mTempfd, &userinfo, sizeof(UserInfo));
if(result < 0)
{
LOG(TAG, "write login info error ...");
return false;
}
LOG(TAG, "write userinfo success ...");
return true;
}
//send online list to client
bool Server::WriteToClient()
{
int result = 0;
OnlineUser *p = mUhead;
Package *pack = (Package *)malloc(sizeof(Package) + sizeof(OnlineUser));
pack->type = GETONLINECLIENT;
pack->length = sizeof(OnlineUser);
while(p)
{
memcpy(pack->data, p, pack->length);
result = write(mTempfd, pack, sizeof(Package) + sizeof(OnlineUser));
if(result < 0)
{
LOG(TAG, "write error ...");
return false;
}
p = p->next;
}
pack->type = ZERO;
result = write(mTempfd, pack, sizeof(Package));
if(result < 0)
{
LOG(TAG, "write error ...");
return false;
}
LOG(TAG, "write user list success ...");
OnlineUser *pshow = mUhead;
qDebug() << "server:\tname\tId";
while(pshow)
{
qDebug() << "server:\t" << pshow->user << "\t" << pshow->fd;
pshow = pshow->next;
}
return true;
}
//write message to client
bool Server::WriteToClient(const Message &messageinfo)
{
int result = 0;
Package *pack = new Package[sizeof(Message) + sizeof(Package)];
pack->type = MESSAGE;
pack->length = sizeof(Message);
memcpy(pack->data, &messageinfo, pack->length);
result = write(messageinfo.receiverid, pack, sizeof(Package) + sizeof(Message));
if(result < 0)
{
LOG(TAG, "write message error ...");
return false;
}
pack->type = ZERO;
result = write(messageinfo.receiverid, pack, sizeof(Package));
if(result < 0)
{
LOG(TAG, "write pack head error ...");
return false;
}
delete pack;
return true;
}
bool Server::ReadFromClient()
{
return true;
}
//select client
bool Server::SelectClient()
{
FD_ZERO(&mSet);
FD_SET(mSocketfd, &mSet);
mMaxfd = mSocketfd;
while(!mIsStop)
{
mReadset = mSet;
int result = 0;
LOG(TAG, "select ...");
result = select(mMaxfd + 1, &mReadset, NULL, NULL, NULL);
if(result < 0)
{
LOG(TAG, "select error ...");
return false;
}
if(FD_ISSET(mSocketfd, &mReadset))
{
socklen_t len = sizeof(mCaddr);
mAcceptfd = accept(mSocketfd, (sockaddr *)&mSaddr, &len);
if(mAcceptfd < 0)
{
LOG(TAG, "accept error ...");
return false;
}
LOG(TAG, "Client: ", inet_ntoa(mSaddr.sin_addr));
FD_SET(mAcceptfd, &mSet);
if(mMaxfd < mAcceptfd)
{
mMaxfd = mAcceptfd;
}
//ClientNode *pnode = new ClientNode[sizeof(ClientNode)];
mNode = (ClientNode *)malloc(sizeof(ClientNode));
mNode->fd = mAcceptfd;
mNode->caddr = mCaddr;
mNode->next = mHead;
mHead = mNode;
}
for(mNode = mHead; mNode != NULL; mNode = mNode->next)
{
mTempfd = mNode->fd;
if(!FD_ISSET(mTempfd, &mReadset))
{
continue;
}
Package pack;
result = read(mTempfd, &pack, sizeof(Package));
if(result < 0)
{
LOG(TAG, "read error and TCP broken ...");
DeleteUnlineUser(mTempfd);
close(mTempfd);
FD_CLR(mTempfd, &mSet);
break;
}
else if(0 == result)
{
LOG(TAG, "TCP broken ...");
DeleteUnlineUser(mTempfd);
close(mTempfd);
FD_CLR(mTempfd, &mSet);
break;
}
bool IsBreak = false;
char name[66];
UserInfo userinfo;
int online;
switch(pack.type)
{
case REGIST://数据包类型为注册
result = read(mTempfd, &mUser, pack.length);
if(result < 0)
{
LOG(TAG, "read user regist info error ...");
return false;
}
LOG(TAG, "read regist image path = ", mUser.imagepath);
if(mStorage->WriteToStorage(mUser))
{
WriteToClient(SUCCESSED);
}
else
{
WriteToClient(FAILED);
}
break;
case LOGIN://数据包类型为登录
result = read(mTempfd, &mLogin, pack.length);
if(result < 0)
{
LOG(TAG, "read login info error ...");
return false;
}
LOG(TAG, "read login name = ", mLogin.username);
LOG(TAG, "read login password = ", mLogin.password);
if(mStorage->ReadFromStorage(mLogin.username, mLogin.password))
{
CreateOnlineLinkTable(mTempfd, mLogin.username);
WriteToClient(SUCCESSED);
}
else
{
WriteToClient(FAILED);
}
break;
case GETLOGININFO://包头表示获取登录成功用户自身信息
result = read(mTempfd, name, pack.length);
if(result < 0)
{
LOG(TAG, "read user name error ...");
return false;
}
LOG(TAG, "read username = ", name);
userinfo = mStorage->ReadFromStorage(name);
WriteT
一款基于Ubuntu16.04的QT界面局域网聊天系统.zip
需积分: 0 125 浏览量
更新于2023-12-31
收藏 451KB ZIP 举报
QT,C++使用技巧,实战应用开发小系统参考资料,源码参考。
详细介绍了一些Qt框架的各种功能和模块,以及如何使用Qt进行GUI开发、网络编程和跨平台应用开发等。
适用于初学者和有经验的开发者,能够帮助你快速上手Qt并掌握其高级特性。
白话Learning
- 粉丝: 4725
- 资源: 3085
最新资源
- 基于Node.js和WebSocket的音频数据流分析音乐节奏展示设计源码
- 基于Surface框架的CURD和后台页面快速搭建设计源码
- 基于Snowflake算法的分布式唯一ID生成器UidGenerator在SpringBoot中的整合与应用设计源码
- 四轴直交机械手工程图机械结构设计图纸和其它技术资料和技术方案非常好100%好用.zip
- 基于Java语言的RabbitMQ精品课程设计源码
- 四合一测试设备(含bom)sw17可编辑工程图机械结构设计图纸和其它技术资料和技术方案非常好100%好用.zip
- 基于SSM框架和JavaScript的教材管理系统设计源码
- 基于JqueryMobile框架的kLink通讯录应用设计源码
- 基于2024暑假鸿蒙应用师资班培训的TeachObject20240715_01设计源码
- 卧式气动膏体灌装机工程图机械结构设计图纸和其它技术资料和技术方案非常好100%好用.zip
- 基于Vue的JavaScript光雨电子书后台源码
- 基于山东大学经验的转专业学生攻略设计源码
- 基于51单片机的蓝牙循迹小车设计源码
- Teaching Small Language Models to Reason 小模型如何在大模型中生效
- 基于Html和Ruby语言的test项目设计源码
- 线材激光焊接裁断机工程图机械结构设计图纸和其它技术资料和技术方案非常好100%好用.zip