libwebsocket: How to disconnect client if there is no server response for a while (with timeout)? - libwebsockets

I have a client using libwebsocket to establish a connection to a server. Whenever the client sends a request, the server sends a response and after receiving the response the client closes the connection. Works fine.
But when the server does not answer to the request i have the problem that the client keeps waiting for a response forever. When nothing happens the callback is never called and its not possible to close connection with returning -1 from callback function.
Is there any way to enable a timeout for the connection to close? Or any possibility to close connection from outside the callback function?
Here is my code so far:
int callback_function(libwebsocket_context* context, libwebsocket* wsi, enum libwebsocket_callback_reasons reason, void* user, void* in, size_t len) {
switch (reason) {
case LWS_CALLBACK_CLIENT_ESTABLISHED: {
std::cout << "LWS_CALLBACK_CLIENT_ESTABLISHED" << std::endl;
libwebsocket_callback_on_writable(context, wsi);
}
break;
case LWS_CALLBACK_CLOSED:{
std::cout << "LWS_CALLBACK_CLOSED" << std::endl;
}
break;
case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
case LWS_CALLBACK_CLIENT_RECEIVE:{
std::cout << "LWS_CALLBACK_CLIENT_RECEIVE" << endl;
((char *)in)[len] = '\0';
answers_[current_request] = answers_[current_request] + string((char *)in);
if (libwebsocket_is_final_fragment(wsi)){
std::cout << "request:" << requests_[current_request] << std::endl;
std::cout << "answer:" << answers_[current_request] << std::endl;
current_request++;
if(current_request >= answers_.size()) {
ready = true;
return -1;
}
libwebsocket_callback_on_writable(context, wsi);
}
}
break;
case LWS_CALLBACK_CLIENT_WRITEABLE:{
std::cout << "LWS_CALLBACK_CLIENT_WRITEABLE" << endl;
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 + LWS_SEND_BUFFER_POST_PADDING];
const std::string message = std::string(requests_[current_request]);
std::copy(message.begin(), message.end(), &buf[LWS_SEND_BUFFER_PRE_PADDING]);
buf[LWS_SEND_BUFFER_PRE_PADDING+(int)message.size()]='\0';
int n = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], (size_t)message.size(), static_cast<libwebsocket_write_protocol>(LWS_WRITE_BINARY));
if (n < 0){
std::cout << kLogErr << "bad things are happening" << std::endl;
return -1;
}
if (n < (int)message.size()) {
std::cout << kLogErr << "Partial write LWS_CALLBACK_CLIENT_WRITEABLE" << std::endl;
return -1;
}
}
break;
default:
std::cout << "CALLBACK_DEFAULT: " << reason << endl;
break;
}
return 0;
}
vector<string> sendMessage(const string& server, int port, const string& path, const vector<string>& messages, bool& error) {
ready = error = false;
current_request = 0;
requests_ = vector<string>(messages);
answers_ = vector<string>(requests_.size(), "");
int ietf_version = -1; /* latest */
wsi_ = libwebsocket_client_connect(context_, server.c_str(), port, 2, path.c_str(), server.c_str(), "origin", NULL, ietf_version);
if (wsi_ == NULL) {
std::cout << kLogErr << "libwebsocket connect failed server:" << server << " port: " << port << " path: " << path << std::endl;
error = true;
return vector<string>();
}
bool first_time = true;
int n = 0;
while (n >= 0 && !force_exit && !ready) {
n = libwebsocket_service(context_, 0);
if(first_time) {
libwebsocket_callback_on_writable(context_, wsi_);
first_time = false;
}
if (n < 0){
continue;
}
if (wsi_ == NULL) {
break;
}
}
error = !ready;
wsi_ = NULL;
return vector<string>(answers_);
}

You could try using:
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
return -1;
break;
Or
lws_set_timeout
But I'm not a 100% sure that will work, you could also try creating an issue/question on their GitHub, they tend to answer quite fast/clear.
I'm also not sure if you should implement

I solved the problem.
I programmed a timer in
vector<string> sendMessage(const string& server, int port, const string& path, const vector<string>& messages, bool& error)
and when the timeout is reaches, the timer sets a flag and triggers
libwebsocket_callback_on_writable(context_, wsi_);
again. Then in
int callback_function(libwebsocket_context* context, libwebsocket* wsi, enum libwebsocket_callback_reasons reason, void* user, void* in, size_t len)
in case
LWS_CALLBACK_CLIENT_WRITEABLE
i check the flag and if it is set the callback is aborted with
return -1;
Works fine!

Related

Unhandled exception at 0x006A549C in myApplication.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x01202FFC)

I am writing a program with C++ that needs to read a CSV file and store it in a binary search tree. But, when the program is reading the file, it fails in the library debugger.jmc.c and in the method void __fastcall __CheckForDebuggerJustMyCode(unsigned char *JMC_flag). Could someone help me? Thanks!
#include <algorithm>
#include <iostream>
#include <ctime>
#include <string>
#include "CSVparser.hpp"
using namespace std;
using namespace std;
struct Bid {
string bidId;
string title;
string fund;
double amount;
Bid() {
amount = 0.0;
}
};
struct Node {
Bid bid;
Node* left;
Node* right;
Node() {
left = nullptr;
right = nullptr;
}
Node(Bid aBid) : Node() {
this->bid = aBid;
}
};
class BinarySearchTree {
private:
Node* root;
void addNode(Node* node, Bid bid);
void inOrder(Node* node);
Node* removeNode(Node* node, string bidId);
public:
BinarySearchTree();
virtual ~BinarySearchTree();
void InOrder();
void Insert(Bid bid);
void Remove(string bidId);
Bid Search(string bidId);
Node* SearchNode(Node* node, string bidId);
};
BinarySearchTree::BinarySearchTree() {
root = nullptr;
}
/**
* Destructor
*/
BinarySearchTree::~BinarySearchTree() {
// recurse from root deleting every node
}
/**
* Traverse the tree in order
*/
void BinarySearchTree::InOrder() {
}
/**
* Insert a bid
*/
void BinarySearchTree::Insert(Bid bid) {
// FIXME (2a) Implement inserting a bid into the tree
if (root == nullptr) {
root = new Node(bid);
}
else {
addNode(root, bid);
}
}
/**
* Remove a bid
*/
void BinarySearchTree::Remove(string bidId) {
// FIXME (4a) Implement removing a bid from the tree
Node* nodePtr = SearchNode(root, bidId);
if (nodePtr == nullptr) {
return;
}
else {
//not yet implemented
}
}
/**
* Search for a bid
*/
Bid BinarySearchTree::Search(string bidId) {
// FIXME (3) Implement searching the tree for a bid
}
void BinarySearchTree::addNode(Node* node, Bid bid) {
// FIXME (2b) Implement inserting a bid into the tree))
//if node is larger than the bid add to the left subtree
if (stoi(node->bid.bidId) > stoi(bid.bidId)) {
if (node->left == nullptr) {
node->left = new Node(bid);
}
else {
addNode(node->left, bid);
}
}
//add to right subtree
else {
if (node->right == nullptr) {
node->right = new Node(bid);
}
else {
addNode(node->right, bid);
}
}
return;
}
void displayBid(Bid bid) {
cout << bid.bidId << ": " << bid.title << " | " << bid.amount << " | "
<< bid.fund << endl;
return;
}
/**
* Load a CSV file containing bids into a container
*
* #param csvPath the path to the CSV file to load
* #return a container holding all the bids read
*/
void loadBids(string csvPath, BinarySearchTree* bst) {
cout << "Loading CSV file " << csvPath << endl;
// initialize the CSV Parser using the given path
csv::Parser file = csv::Parser(csvPath);
try {
for (unsigned int i = 0; i < file.rowCount(); i++) {
// Create a data structure and add to the collection of bids
Bid bid;
bid.bidId = file[i][1];
bid.title = file[i][0];
bid.fund = file[i][8];
bid.amount = strToDouble(file[i][4], '$');
// push this bid to the end
bst->Insert(bid);
}
}
catch (csv::Error& e) {
std::cerr << e.what() << std::endl;
}
}
double strToDouble(string str, char ch) {
str.erase(remove(str.begin(), str.end(), ch), str.end());
return atof(str.c_str());
}
int main(int argc, char* argv[]) {
// process command line arguments
string csvPath, bidKey;
switch (argc) {
case 2:
csvPath = argv[1];
bidKey = "98105";
break;
case 3:
csvPath = argv[1];
bidKey = argv[2];
break;
default:
csvPath = "eBid_Monthly_Sales_Dec_2016.csv";
bidKey = "98105";
}
clock_t ticks;
// Define a binary search tree to hold all bids
BinarySearchTree* bst = nullptr;
Bid bid;
int choice = 0;
while (choice != 9) {
cout << "Menu:" << endl;
cout << " 1. Load Bids" << endl;
cout << " 2. Display All Bids" << endl;
cout << " 3. Find Bid" << endl;
cout << " 4. Remove Bid" << endl;
cout << " 9. Exit" << endl;
cout << "Enter choice: ";
cin >> choice;
switch (choice) {
case 1:
bst = new BinarySearchTree();
ticks = clock();
loadBids("eBid_Monthly_Sales.csv", bst);
//cout << bst->Size() << " bids read" << endl;
// Calculate elapsed time and display result
ticks = clock() - ticks;
cout << "time: " << ticks << " clock ticks" << endl;
cout << "time: " << ticks * 1.0 / CLOCKS_PER_SEC << " seconds" << endl;
break;
case 2:
bst->InOrder();
break;
case 3:
ticks = clock();
bid = bst->Search(bidKey);
ticks = clock() - ticks; // current clock ticks minus starting clock ticks
if (!bid.bidId.empty()) {
displayBid(bid);
}
else {
cout << "Bid Id " << bidKey << " not found." << endl;
}
cout << "time: " << ticks << " clock ticks" << endl;
cout << "time: " << ticks * 1.0 / CLOCKS_PER_SEC << " seconds" << endl;
break;
case 4:
bst->Remove(bidKey);
break;
}
}
cout << "Good bye." << endl;
return 0;
}

how to implement onvif CreatePullPointSubscription operation by gsoap

Referring to onvif core specification: If the subscription is accepted, the response contains a WS-EndpointReference to the
instantiated pull point. This WS-Endpoint provides a PullMessages operation, which is
used by the client to retrieve Notifications.
But I can't see the codes about instancing pull point, and I don't know how to implement it. Here is my coding.
SOAP_FMAC5 int SOAP_FMAC6 __tev__CreatePullPointSubscription(struct soap* soap, struct _tev__CreatePullPointSubscription *tev__CreatePullPointSubscription, struct _tev__CreatePullPointSubscriptionResponse *tev__CreatePullPointSubscriptionResponse)
{
tev__CreatePullPointSubscriptionResponse->SubscriptionReference.Address = (char *)soap_malloc(soap, sizeof(char) * 128);
strcpy(tev__CreatePullPointSubscriptionResponse->SubscriptionReference.Address, "http://192.168.12.1/Subscription?Idx=0");
tev__CreatePullPointSubscriptionResponse->wsnt__CurrentTime=time(NULL);
tev__CreatePullPointSubscriptionResponse->wsnt__TerminationTime=tev__CreatePullPointSubscriptionResponse->wsnt__CurrentTime+60;
return SOAP_OK;
}
Can anyone brighten me? Thank you in advance.
void CreatePullPointSubscription() {
struct soap *m_soap = soap_new();
m_soap->connect_timeout = SOAP_REQUEST_TIMEOUT_IN_SECONDS;
m_soap->recv_timeout = SOAP_REQUEST_TIMEOUT_IN_SECONDS;
m_soap->send_timeout = SOAP_REQUEST_TIMEOUT_IN_SECONDS;
PullPointSubscriptionBindingProxy subscriptionProxy(m_soap);
subscriptionProxy.soap_endpoint = xAddr;
if (addCredentialsToCall(m_soap)) {
_tev__CreatePullPointSubscription request;
_tev__CreatePullPointSubscriptionResponse response;
auto ret = subscriptionProxy.CreatePullPointSubscription(&request, response);
if (ret != SOAP_OK) {
soap_stream_fault(m_soap, std::cerr);
} else {
auto address = response.SubscriptionReference.Address;
std::cout << address << std::endl;
std::cout << "Subscription metadata: " << response.SubscriptionReference.Metadata << std::endl;
std::cout << "Termination time " << response.wsnt__TerminationTime << std::endl;
std::cout << "Current time " << response.wsnt__CurrentTime << std::endl;
std::string uuid = std::string(soap_rand_uuid(m_soap, "urn:uuid:"));
struct SOAP_ENV__Header header;
header.wsa5__MessageID = (char *) uuid.c_str();
header.wsa5__To = response.SubscriptionReference.Address;
m_soap->header = &header;
if (addCredentialsToCall(m_soap)) {
_tev__PullMessages tev__PullMessages;
tev__PullMessages.Timeout = "PT600S";
tev__PullMessages.MessageLimit = 100;
_tev__PullMessagesResponse tev__PullMessagesResponse;
auto ret = subscriptionProxy.PullMessages(&tev__PullMessages, tev__PullMessagesResponse);
for (auto msg : tev__PullMessagesResponse.wsnt__NotificationMessage) {
std::cout << "\tMessage is :" << msg->Topic->__mixed << std::endl;
}
} else {
std::cout << "Couldn't set credentials!!!" << std::endl;
}
}
}
subscriptionProxy.destroy();
}
This worked for me atleast to pull the event initializers.

Unreliable Unix Socket Connection

I have created a basic client/server c++ socket program. I can write integers over the socket reliably, but when I try to write a string over the socket the receiving end only receives the data about 25% of the time. I have used Wireshark to verify that the data is being sent. I am new to c++ and network programming so any input would be appreciated. The code is below.
class compressionServer{
int PORT = 4000;
int LISTEN_QUEUE = 1024;
int sock;
int conn;
struct sockaddr_in socketAddress;
int receivedMagicData[8+1];
int receivedStatusCode[2];
int receivedPayloadLength[2];
char receivedCompressionData[2048];
int requestCode = 0;
int payloadLength;
uint32_t inBytes = 0;
uint32_t outBytes = 0;
double compressionRatio = 0;
string dataToCompress;
public:
void start(){
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("Socket Error");
exit(1);
}
bzero(&socketAddress, sizeof(socketAddress));
socketAddress.sin_family = AF_INET;
socketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
socketAddress.sin_port = htons(PORT);
int enable = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0){ // so we can rebind quickly while testing
printf("setsockopt(SO_REUSEADDR) failed");
}
if(::bind(sock, (struct sockaddr *) &socketAddress, sizeof(socketAddress)) < 0){
printf("Bind Error\n");
std::cout << std::strerror(errno) << std::endl;
exit(1);
}
if(listen(sock, LISTEN_QUEUE) < 0){
printf("Listen Error");
exit(1);
}
for ( ; ; ) {
if((conn = accept(sock, (struct sockaddr *) NULL, NULL)) < 0){
printf("Accept Error");
exit(1);
}
ssize_t n;
if((n = read(conn, receivedMagicData, 8)) > 0){
int magicWord = ntohl(*receivedMagicData);
if(magicWord == 53545259){
std::cout << "DOES NOT MATCH" << std::endl;
break;
}
}
if((n = read(conn, receivedPayloadLength, 2)) > 0){
payloadLength = ntohs(*receivedPayloadLength);
std::cout << "payloadLength = " << std::hex << payloadLength << std::endl;
}
if((n = read(conn, receivedStatusCode, 2)) > 0){
requestCode = ntohs(*receivedStatusCode);
std::cout << "requestCode = " << std::hex << requestCode << std::endl;
}
while((n = read(conn, receivedCompressionData, 2048)) > 0){
receivedCompressionData[n] = 0;
cout << "data: " << receivedCompressionData << endl;
dataToCompress = receivedCompressionData;
if(strlen(receivedCompressionData) > 0){
break;
}
}
}
if (close(conn) < 0){
printf("Close Error");
exit(1);
}
}
};
The server class essential is expecting to receive 12 bytes of data as the header and after that up to 2048 bytes as the characters. This is the part only coming through a fraction of the time.
class compressionClient{
public:
void start(std::string ipAddr){
int MAX_LINE = 4096;
int sockfd;
struct sockaddr_in servaddr;
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("socket error");
exit(1);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(4000);
if (inet_pton(AF_INET, ipAddr.c_str(), &servaddr.sin_addr) <= 0){
printf("inet_pton error for %s", ipAddr.c_str());
exit(1);
}
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){
printf("connect error");
exit(1);
}
long headerHex = htonl(0x53545259);
long header2Hex = htonl(0x31300034);
std::cout << "send: " << std::hex << headerHex << std::endl;
std::cout << "send2: " << std::hex << header2Hex << std::endl;
//server receives this
if(send(sockfd, (char *) (&headerHex), sizeof(headerHex), 0) < 0){
printf("Write Error");
exit(1);
}
//server receives this too
if(send(sockfd, (char *) (&header2Hex), sizeof(header2Hex), 0) < 0){
printf("Write Error2");
exit(1);
}
char data[100];
snprintf(data, sizeof(data), "aaabbcddd");
//server only recieves this sometimes
if(write(sockfd, data, strlen(data)) < 0){
printf("write error3");
exit(1);
}
}
};

boost::asio::read throws compilation error 'read_some' is not a member of 'boost::shared_ptr<boost::asio::ip::tcp::socket>'

I am trying to build up a client to get data via a specific protocol from a server.
I know that my code is not the best - but at the moment I am still experimenting with the basic functions of Boost ASIO.
I want to implement an read from TCP-Function which blocks until a specific amount of bytes have been received.
My Problem:
When I call boost::asio::read or boost::asio::write i geht following error:
error C2039: 'read_some' : is not a member of boost::shared_ptr'
I am working with VS2013 Professional, Boost 1.55.00 (precompiled).
Here is my Code: ( You can find the line by the comment "//HEEERE"
boost::mutex cout_lock;
int main()
{
// creating io_service
boost::shared_ptr<boost::asio::io_service> io_service(new boost::asio::io_service);
// creating work and assigning it to io_service
boost::shared_ptr<boost::asio::io_service::work> work(new boost::asio::io_service::work(*io_service));
// creating strand and assigning it to io_service
boost::shared_ptr<boost::asio::io_service::strand> strand(new boost::asio::io_service::strand(*io_service));
// creating socket
boost::shared_ptr<boost::asio::ip::tcp::socket> socket(new boost::asio::ip::tcp::socket(*io_service));
try {
// creating resolver
boost::asio::ip::tcp::resolver resolver(*io_service);
// creating query
boost::asio::ip::tcp::resolver::query query(IPConfig_str, boost::lexical_cast<std::string>(IPConfig_PortNr));
// creating iterator
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
// creating endpoint
boost::asio::ip::tcp::endpoint endpoint = *iterator;
// connecting synchronously
socket->connect(endpoint);
}
catch(std::exception &ex) {
cout_lock.lock();
std::cout << "[main]:\t" << "Exception:" << ex.what() << std::endl;
cout_lock.unlock();
}
// Create Query
CommandCreator CMDCreator;
Command sendCommand;
CMDCreator.Create_fpga_GetSwVers(&sendCommand);
std::cout << std::endl;
std::cout << "SENT:" << std::endl;
for (int i = 0; i < sendCommand.length; i++)
{
std::cout << std::hex << std::setw(2) << std::setfill('0') << int(sendCommand.buffer[i]) << ", ";
}
std::cout << std::endl;
// Send Query
boost::system::error_code ec;
socket->async_send(boost::asio::buffer(sendCommand.buffer, sendCommand.length), boost::asio::transfer_all());
Sleep(300); // sleep 100 ms (at least 85 <- not stable!)
// Receive Answer - Header
Command receiveCommandHeader;
receiveCommandHeader.InitBuffer(4);
// Async
// socket->async_receive(boost::asio::buffer(receiveCommandHeader.buffer, receiveCommandHeader.length), 0, boost::bind(HandleRead, ec));
//HEEERE
boost::asio::read(socket, boost::asio::buffer(receiveCommandHeader.buffer, receiveCommandHeader.length), boost::asio::transfer_all(), ec);
//shutting down
socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
socket->close(ec);
io_service->stop();
return 0;
}
class Command
{
friend class CommandCreator; // TODO: is there a better and as simple method as a friend class?
public:
Command() : buffer(0)
{}
virtual ~Command()
{
delete[] buffer;
buffer = 0;
}
void InitBuffer(int const len)
{
this->length = len;
this->buffer = new uint8_t[len];
}
uint8_t* buffer;
int length;
};
Actually the problem is located at this part of boost in the file read.hpp, where async_read_some is called from 'stream_'.
void operator()(const boost::system::error_code& ec,
std::size_t bytes_transferred, int start = 0)
{
std::size_t n = 0;
switch (start_ = start)
{
case 1:
n = this->check_for_completion(ec, total_transferred_);
for (;;)
{
stream_.async_read_some(
boost::asio::buffer(buffer_ + total_transferred_, n),
BOOST_ASIO_MOVE_CAST(read_op)(*this));
return; default:
total_transferred_ += bytes_transferred;
if ((!ec && bytes_transferred == 0)
|| (n = this->check_for_completion(ec, total_transferred_)) == 0
|| total_transferred_ == boost::asio::buffer_size(buffer_))
break;
}
handler_(ec, static_cast<const std::size_t&>(total_transferred_));
}
}
Okey, I've just found the problem.
// creating socket
boost::shared_ptr<boost::asio::ip::tcp::socket> socket(new boost::asio::ip::tcp::socket(*io_service));
I created the socket as a pointer but all the interfaces of read, read_some and other boost-library functions require the object. Therefore adding the dereferencing operator did it:
boost::asio::async_read(*socket, boost::asio::buffer(receiveCommandHeader.buffer, receiveCommandHeader.length),
boost::asio::transfer_all(), boost::bind(HandleRead, ec));

boost::asio::async_write not writing to clients properly, weird behaviour

I have written a program that accepts N client connections and then writes data into them. The problem I am having now is: I can only write to N-1 clients, the first one is never written to. I have no idea why this is happening and so I wish some of you might be able to provide some assistance.
I have provided the portion of code that may be associated with this problem:
void ClientPartitionServer::AcceptClientConnections(int port) {
cout << "Listening to connections..." << endl;
cout << "Number of PartitionInstanceConnections: " <<
m_partitionInstanceConnections.size() << endl;
m_acceptor = new boost::asio::ip::tcp::acceptor(m_IOService);
m_endpoint = new boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),
m_port);
m_acceptor->open(m_endpoint->protocol());
m_acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
m_acceptor->bind(*m_endpoint);
m_acceptor->listen();
boost::asio::ip::tcp::socket* acceptingSocket =
new boost::asio::ip::tcp::socket(m_IOService);
m_acceptor->async_accept(*acceptingSocket, boost::bind(
&ClientPartitionServer::HandleAccept, this, acceptingSocket,
boost::asio::placeholders::error));
}
void ClientPartitionServer::HandleAccept(boost::asio::ip::tcp::socket* socket,
const boost::system::error_code& error) {
cout << "Connection established..." << endl;
m_clientSockets.push_back(new boost::asio::ip::tcp::socket(m_IOService));
cout << m_clientSockets.back()->is_open() << endl;
++m_clientSocketsCounter;
cout << "ClientPartitionServer identifier: " << m_identifier << endl;
cout << "Client connected on port: " << m_port << endl;
cout << "Number of clients on port: " << m_clientSocketsCounter <<
endl;
m_acceptor->async_accept(*m_clientSockets.back(), boost::bind(
&ClientPartitionServer::HandleAccept, this, m_clientSockets.back(),
boost::asio::placeholders::error));
}
void ClientPartitionServer::HandleSignal(char* content, int transferSize,
int identifier) {
if(identifier == m_identifier) {
TransferToQueueBuffer(content, transferSize);
if(m_writeCompleteFlag) {
TransferToWriteBuffer(m_queueBuffer, m_queueBufferSize);
if(m_clientSockets.size() != 0) {
for(vector<boost::asio::ip::tcp::socket*>::const_iterator i =
m_clientSockets.begin(); i != m_clientSockets.end(); ++i) {
WriteToClient(m_writeBuffer, m_queueBufferSize, *i);
}
}
}
}
}
void ClientPartitionServer::WriteToClient(char* content, int transferSize,
boost::asio::ip::tcp::socket* clientSocket) {
boost::lock_guard<boost::mutex> lock(m_writeToClientMutex);
m_writeCompleteFlag = false;
boost::asio::async_write(*clientSocket, boost::asio::buffer("ABC ",
4), boost::bind(&ClientPartitionServer::HandleWrite,
this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void ClientPartitionServer::HandleWrite(const boost::system::error_code& ec,
size_t bytes_transferred) {
cout << "handlewrite" << endl;
m_writeCompleteFlag = true;
}
Thank you for any assistance.
The first async_accept() is called on acceptingSocket which is new'd in AcceptClientConnections() and leaked.
The subsequent async_accept()s are called on sockets that are new'd in HandleAccept() and push_back()'ed into m_clientSockets.
WriteToClient() is executed only on the sockets found in m_clientSockets, never on the first socket.
Solution: push_back that first socket in AcceptClientConnections() into m_clientSockets too.

Resources