设为首页 收藏本站
查看: 718|回复: 0

[经验分享] Linux socket编程(三) 简单的多线程聊天室

[复制链接]

尚未签到

发表于 2015-3-7 03:58:49 | 显示全部楼层 |阅读模式
  要用到多线程以及线程的读写锁,之前写的Socket类、ServerSocket要做相应的改变
  因为服务器端要维持着一个存储客户端Socket信息到数据结构,当多个线程同时访问这个结构时,要做同步处理,所以要在适当的时候加上读锁或写锁。
  新的ServerSocket类

#ifndef SERVERSOCKET_H
#define SERVERSOCKET_H
#include "Socket.h"
#include
#include
#include "ThreadReadWriteLock.h"
using std::list;
class ServerSocket:public Socket
{
public:
ServerSocket(const int port);
ServerSocket();
virtual ~ServerSocket();
void Accept(Socket& socket);
//run server to connect multi-clients
void Run();
private:
//accept multi-clients
bool Accept();
void AddClient(Socket* clientSocket);
static void DeleteClient(Socket* clientSocket);
static void* ProcessMessage(void* arg);
static void SendMsgToAllUsers(const std::string& message);
static list clientSockets;
static bool serviceFlag;
//use thread-read-write-lock to synchronize threads
static ThreadReadWriteLock readWriteLock;
};
#endif
  其中有static成员函数,因为创建一个新的线程时,要传递一个函数指针,不过类普通的成员函数的函数指针与一般的函数指针是不兼容的,所以要传递static成员函数的函数指针。
  以下是ServerSocket的新实现:
  ServerSocket.cpp

#include "ServerSocket.h"
#include "SocketException.h"
#include
#include
list ServerSocket::clientSockets;
ThreadReadWriteLock ServerSocket::readWriteLock;
bool ServerSocket::serviceFlag=true;
ServerSocket::ServerSocket(const int port)
{
if ( ! Socket::Create() )
{
throw SocketException ( "Could not create server socket." );
}
if ( ! Socket::Bind ( port ) )
{
throw SocketException ( "Could not bind to port." );
}
if ( ! Socket::Listen() )
{
throw SocketException ( "Could not listen to socket." );
}
}
ServerSocket::~ServerSocket()
{
list::iterator iter;
for(iter=clientSockets.begin();iter!=clientSockets.end();iter++)
delete (*iter);
}
void ServerSocket::Accept(Socket& socket)
{
if ( ! Socket::Accept ( socket ) )
{
throw SocketException ( "Could not accept socket." );
}
}
bool ServerSocket::Accept()
{
Socket* clientSocket=new Socket;
Accept(*clientSocket);
AddClient(clientSocket);
//create new thread for a new client
    pthread_t newThread;
int result=pthread_create(&newThread,NULL,ProcessMessage,static_cast(clientSocket));
if(result!=0)
return false;
    //detach the newThread
    //so when newThread exits it can release it's resource
    result=pthread_detach(newThread);
    if(result!=0)
        perror("Failed to detach thread");

return true;
}
void ServerSocket::Run()
{
while(serviceFlag)
{
if(clientSockets.size()>=static_cast(MAXCONNECTION))
serviceFlag=false;
else
serviceFlag=Accept();
sleep(1);
}
}
void* ServerSocket::ProcessMessage(void* arg)
{
std::string message;
Socket* clientSocket=static_cast(arg);
Send(*clientSocket,"Welcome!");
while(serviceFlag)
{
Receive(*clientSocket,message);
if(message=="exit")
{
Send(*clientSocket,"user_exit");
DeleteClient(clientSocket);
break;
}
else
SendMsgToAllUsers(message);
sleep(1);
}
pthread_exit(NULL);
return NULL;
}

void ServerSocket::AddClient(Socket* socket)
{
if(readWriteLock.SetWriteLock())
{
clientSockets.push_back(socket);
std::cout

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-44078-1-1.html 上篇帖子: Linux学习之CentOS(三十五)--配置域从DNS服务器以及缓存DNS服务器 下篇帖子: Linux socket编程(一) 对套接字操作的封装
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表