Home  +  Forums  +  C++ and Sockets  +  C++ and SQL: MySQL, sqlite, ODBC  +  Miscellaneous Projects
Logo
~Sockets~
~New~
~Examples~
~Contact~

C++ Socket library tutorial

New in 2.0: threadsafe operation

Prev   |   Menu   |   Next

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);
	}
}



Prev   |   Menu   |   Next

Valid HTML 4.01!

Validate
Page, code, and content Copyright (C) 2021 by Anders Hedström