 ~Sockets~
|
C++ Socket library tutorial
|
|
New in 2.0: threadsafe operation
Included in 2.0 is a way to build threadsafe socket applications.
By using a mutex and giving it to the sockethandler when the sockethandler is created,
all internal operations of the sockethandler will be protected by that mutex.
When another thread wants to use the sockethandler, it must first get and lock the
mutex.
Demonstration of threadsafe socket operation.
This small program have two types of sockets. The InfoSocket always runs in the main process,
and receives events from any MySocket that connects/sends data.
The MySocket detaches on accept, and sends information to all connected InfoSocket's.
threadsafe.cpp
#include <stdio.h>
#include <SocketHandler.h>
#include <TcpSocket.h>
#include <Mutex.h>
#include <StdoutLog.h>
#include <ListenSocket.h>
#include <Lock.h>
class InfoSocket : public TcpSocket
{
public:
InfoSocket(ISocketHandler& h) : TcpSocket(h) {}
~InfoSocket() {}
void OnAccept() {
Send("Welcome, " + GetRemoteAddress() + "\n");
}
};
class MyHandler : public SocketHandler
{
public:
MyHandler(IMutex& m,StdoutLog *p) : SocketHandler(m, p) {}
~MyHandler() {}
void SendInfo(const std::string& msg) {
for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
{
InfoSocket *p = dynamic_cast<InfoSocket *>((*it).second);
if (p)
{
p -> Send(msg);
}
}
}
};
class MySocket : public TcpSocket
{
public:
MySocket(ISocketHandler& h) : TcpSocket(h) {
SetLineProtocol();
}
~MySocket() {}
void OnAccept() {
Send("Welcome, " + GetRemoteAddress() + "\n");
if (!Detach())
{
SetCloseAndDelete();
}
}
void OnDetached() {
Lock lck(MasterHandler().GetMutex());
static_cast<MyHandler&>(MasterHandler()).SendInfo(GetRemoteAddress() + ": New connection\n");
}
void OnLine(const std::string& line) {
Lock lck(MasterHandler().GetMutex());
static_cast<MyHandler&>(MasterHandler()).SendInfo(GetRemoteAddress() + ": " + line + "\n");
}
};
int main(int argc,char *argv[])
{
Mutex lock;
StdoutLog log;
MyHandler h(lock, &log);
ListenSocket<MySocket> l(h);
if (l.Bind(11001))
{
printf("Bind() failed\n");
exit(-1);
}
h.Add(&l);
ListenSocket<InfoSocket> l2(h);
if (l2.Bind(11002))
{
printf("Bind() failed\n");
exit(-2);
}
h.Add(&l2);
bool quit = false;
while (!quit)
{
h.Select(1, 0);
}
}
|
|
|