Note: I am mixing some C & C++ but it shouldn't be too confusing.
Connected clients are added to a multimap (might aswel have been a map, I know ^^).
The multimap
typedef std::multimap<std::string, SOCKET> clientMap;
typedef std::pair<clientMap::iterator,
clientMap::iterator>
clientIters;
clientMap clientmap;
clientIters clientByID(std::string clientID)
{
return clientmap.equal_range(clientID);
}
Adding a client (each client runs in it's own thread)
//Add clientID to map of clients
if(clientAdded == false)
{
std::stringstream ss;
ss << lpParam; //Use socket# as the unique ID
clientID = ss.str();
clientmap.insert(std::pair<std::string,SOCKET>(clientID,sock));
clientAdded = true;
}
//Client wasn't added correctly!
if(clientID == "" || clientAdded == false)
{
std::cout << "Problem adding client" << std::endl;
}
Server waits for client messages with a blocking recv() call
ret = recv(sock, szBuff, DEFAULT_BUFFER, 0);
if (ret == 0) // Graceful close
break;
else if (ret == SOCKET_ERROR)
{
printf("recv() failed: %d\n", WSAGetLastError());
removeUser(clientID);
break;
}
removeUser() function
void removeUser(std::string clientID)
{
std::cout << "Going to try and remove client: " << clientID << std::endl;
//Remove client
clientIters iters = clientByID(clientID);
clientMap::iterator it = iters.first;
while(it != iters.second)
{
clientmap.erase(it++);
std::cout << "removed client: " << it->first << std::endl;
}
//Show remaining clients
std::cout << "clients left:" << std::endl;
for (clientMap::iterator it = clientmap.begin(); it != clientmap.end(); ++it)
{
std::cout << it->first << std::endl;
}
}
All of this is working fine if I close a client that was connected to either my local IP or external IP (directly).
recv() failed: 10054
Going to try and remove client 0000008C
removed client 0000008C
clients left:
00000084
00000088
But if I put a proxy inbetween (using proxifier), the server thinks the connection is still active or something because the server doesn't do anything when I close the client. It just sits there.. waiting for nothing.
I'm using this socket class as a base but it's pretty heavily modified by now.
How can I make sure a closed client is definitely removed from the multimap?
Could you store some state for each connection? like the last time something was received?
You could then periodically loop through your active connections and prune any that haven't sent anything for a long time, as the connection is more then likely stale.
Related
I'm trying to make a multithreaded server, but for some reason, the threads of my server aren't switching. Only the last thread that was create is running, the other threads aren't running.
This is the code of the main server:
void Server::serve(int port)
{
struct sockaddr_in sa = { 0 };
sa.sin_port = htons(port); // port that server will listen for
sa.sin_family = AF_INET; // must be AF_INET
sa.sin_addr.s_addr = INADDR_ANY; // when there are few ip's for the machine. We will use always "INADDR_ANY"
// Connects between the socket and the configuration (port and etc..)
if (bind(_serverSocket, (struct sockaddr*)&sa, sizeof(sa)) == SOCKET_ERROR)
throw std::exception(__FUNCTION__ " - bind");
std::cout << "binded" << std::endl;
// Start listening for incoming requests of clients
if (listen(_serverSocket, SOMAXCONN) == SOCKET_ERROR)
throw std::exception(__FUNCTION__ " - listen");
std::cout << "Listening on port " << port << std::endl;
while (true)
{
SOCKET client_socket = accept(_serverSocket, NULL, NULL);
if (client_socket == INVALID_SOCKET)
throw std::exception(__FUNCTION__);
std::cout << "Accepting clients..." << std::endl;
std::cout << "Client accepted" << std::endl;
std::thread newClientThread(&Server::clientThread, this, std::ref(client_socket)); // Make thread of client
newClientThread.detach();
}
}
This is the thread of the client:
void Server::clientThread(SOCKET& clientSocket)
{
Helper ourHelper;
std::string msg = "";
int lengthOfMessage = 0;
this->_vectorOfSockets.push_back(clientSocket);
try
{
while (true)
{
std::cout << clientSocket;
/*
// Get message and save into queue
msg = ourHelper.getStringPartFromSocket(clientSocket, 1024);
msg = this->returnFullMsg(msg);
try
{
std::cout << clientSocket << " - d\n";
std::lock_guard<std::mutex> lck(mtx);
std::cout << clientSocket << " - d\n";
this->_messagesQueue.push(msg);
ourConditionVariable.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(1)); // Wait the main thread to take care for the message
}
catch (std::exception e)
{
}*/
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
catch (const std::exception& e)
{
std::cout << "Client logged out\n";
// this->_users.erase(msg.substr(5, atoi(msg.substr(3, 5).c_str() + 5))); // Remove the user from the connected users list
closesocket(clientSocket);
}
}
And this the code of the main thread:
int main()
{
Server myServer;
std::string newMessage;
std::thread ourConnectorThread (connectorThread, std::ref(myServer));
ourConnectorThread.join();
/*std::cout << "Starting...\n";
while (true)
{
std::unique_lock<std::mutex> lckMessages(ourMutex);
ourConditionVariable.wait(lckMessages); // Wait for new message
newMessage = myServer.getQueue().front(); // Get the new message.
myServer.getQueue().pop(); // Remove the first item
takeCareForMessage(newMessage, myServer);
lckMessages.unlock();
}*/
return 0;
}
The code in the comments is irrelevant.
The result of this code is that the last thread is just printing the number of socket every second, and the other threads aren't printing anything..
What is the problem with my code?
One main error in your code is that client_socket is passed by reference, and then it is modified by the server thread. A fix is to pass it by value.
Another error is that _vectorOfSockets.push_back is modified by multiple threads - a race condition. You need to use a mutex to fix that.
accept may fail when a client has disconnected. That's not an unrecoverable exceptional condition, no need to throw an exception, just retry accept to recover.
Update: I can run the server and client perfect locally when they are on the same host. The below scenario is when they are on separate machines(more specifically one is running on ARM64 Petalinux and other on Ubuntu). Perhaps I need to set some options on server side etc
I have a poco websocket server written over the standard sample provided by Poco and a javascript client. While trying to openwebsocket it will get connected in first go sometimes after trying 2-3 times and so on. Now once connected, it might send the message or just gets disconnected on the client side. While on the server side there is no error and I am pretty sure its still open because when i try to open another connection from the client side it will get connected on different client port.
Now the interesting thing is I wrote a Poco websocket client and sending/receiving message continuously without delay in a loop, the client remains active for sometime and then both server and client says Exception connection reset by peer. Next when i put a delay in the loop while sending/receiving messages on client side (say 5s), the client will send/receive for say 3-4 times and then the client encounters Exception connection reset by peer and now this time no such message on server side. Its really boggling me since I couldn't find the solution no matter what i try.
PS: I have timeout of 10 days for websocket server
The server side request handling is as follow:
std::cout << "Request Received" << std::endl;
Poco::Util::Application& app = Poco::Util::Application::instance();
try
{
std::cout << "Trying to connect..." << std::endl;
Poco::Net::WebSocket ws(request, response);
ws.setReceiveTimeout(Poco::Timespan(10, 0, 0, 0, 0)); //Timeout of 10 days
app.logger().information("WebSocket connection established!");
int flags, n;
do
{
char buffer[1024] = {'\0'};
std::cout << "Waiting for incoming frame" << std::endl;
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
strncpy(buffer, "Hello Client!!", 1024);
ws.sendFrame(buffer, strlen(buffer), Poco::Net::WebSocket::FRAME_TEXT);
}
while (n > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE);
std::cout << "Websocket Closed" << std::endl;
app.logger().information("WebSocket connection closed.");
}
catch (std::exception& e)
{
std::cout << "Exception " << e.what() << std::endl;
}
(As one can see, server will post a message when a websocket is closed but nothing is displayed when the client says connection reset by peer)
The poco websocket client side is:
HTTPClientSession cs("IP", port);
HTTPRequest request(HTTPRequest::HTTP_GET, "/?encoding=text",HTTPMessage::HTTP_1_1);
request.set("origin", "http://localhost");
HTTPResponse response;
bool run = true;
try {
WebSocket* m_psock = new WebSocket(cs, request, response);
char buffer[1024] = {'\0'};
std::string str = "Hello Server!!";
do {
char receiveBuff[256];
strncpy(buffer, str.c_str(), 1024);
int len=m_psock->sendFrame(buffer,strlen(buffer),WebSocket::FRAME_TEXT);
std::cout << "Sent bytes " << len << std::endl;
std::cout << "Sent Message: " << buffer << std::endl;
int flags=0;
int rlen=m_psock->receiveFrame(receiveBuff,256,flags);
std::cout << "Received bytes " << rlen << std::endl;
std::cout << receiveBuff << std::endl;
//std::cin >> str;
sleep(5);
} while (1);
m_psock->close();
}
catch (std::exception &e)
{
std::cout << "Exception " << e.what();
}
FYI: I can't process the connection reset by peer, because it directly goes to exception without printing received bytes as 0
I'm currently building a network prototype for SFML using UDP. I've created an application in which you can choose to be the server or the client. So, usually I start up 2 instances of the application, letting one be the server and the other be the client. I'm connecting to my local IP 127.0.0.1.
About 20 minutes ago, this EXACT code worked and I had no problems with it. I didn't change anything, but this code does not work anymore, and the program crashes when I call socket.bind() for the server. Client-side, no errors show up.
This is done in C++.
Does anyone know a possible cause for this? As far as I know, the port is not in use, either.
My client code:
void runUdpClient(unsigned short port){
sf::IpAddress server;
do
{
std::cout << "Type the address or name of the server to connect to: ";
std::cin >> server;
} while (server == sf::IpAddress::None);
sf::UdpSocket socket;
sf::Packet clientSendPacket;
std::string packetSendContent = "Packet data from the client";
clientSendPacket << packetSendContent;
if (socket.send(clientSendPacket, server, port) != sf::Socket::Done)
return;
std::cout << "Message sent to the server: \"" << packetSendContent << "\"" << std::endl;
// Maak variabelen
sf::IpAddress sender;
unsigned short senderPort;
sf::Packet clientReceivePacket;
std::string clientReceiveContent;
if (socket.receive(clientReceivePacket, sender, senderPort) != sf::Socket::Done)
return;
clientReceivePacket >> clientReceiveContent;
std::cout << "Message received from " << sender << ": \"" << clientReceiveContent << "\"" << std::endl;
}
My server code:
void runUdpServer(unsigned short port){
sf::UdpSocket socket;
if (socket.bind(port) != sf::Socket::Done)
std::cout << "Error binding socket for server";
return;
std::cout << "Server is listening to port " << port << ", waiting for a message... " << std::endl;
sf::Packet serverReceivePacket;
std::string serverReceiveContent;
sf::IpAddress sender;
unsigned short senderPort;
if (socket.receive(serverReceivePacket, sender, senderPort) != sf::Socket::Done)
std::cout << "Error receiving packet for server";
return;
serverReceivePacket >> serverReceiveContent;
std::cout << "Message received from client " << sender << ": \"" << serverReceiveContent << "\"" << std::endl;
sf::Packet serverSendPacket;
std::string serverSendContent = "Packet data from server";
serverSendPacket << serverSendContent;
if (socket.send(serverSendPacket, sender, senderPort) != sf::Socket::Done)
std::cout << "Error sending packet from server";
return;
std::cout << "Message sent to the client: \"" << serverSendContent << "\"" << std::endl;
}
In your server code, the if statements are missing braces, so you are ALWAYS executing return as soon as socket.bind() exits, whether it succeeds or fails. This code:
if (socket.bind(port) != sf::Socket::Done)
std::cout << "Error binding socket for server";
return;
Is the same as this code:
if (socket.bind(port) != sf::Socket::Done)
std::cout << "Error binding socket for server";
return;
Which is logically equivalent to this code:
if (socket.bind(port) != sf::Socket::Done) {
std::cout << "Error binding socket for server";
}
return;
Whitespace formatting is not important to C and C++. To perform multiple statements inside the body of an if block, you need explicit braces:
if (socket.bind(port) != sf::Socket::Done)
{
std::cout << "Error binding socket for server";
return;
}
Same with the if statements for your server's calls to socket.receive() and socket.send().
Your client code is not outputting any error messages if socket.send() or socket.receive() fail, those if statements are performing single statements in their body (namely, just return), so braces are optional.
Your server most likely shut down without closing the port properly.
If you wait a few minutes the port will be free to use again (takes about 2-3 minutes on my Ubuntu 16.04 system, might be different depending what OS you use)
Alternatively you can change the port you're using.
The problem was the formatting of the ifs and the returns. After hitting Ctrl+Shift+K, the code got formatted again and it worked.
I'm working on a client application that sends sensor data one way to a remote server. After the initial login there is no return data from the server. My problem is when the ethernet is disconnected such as a hard disconnect i.e. wireless link goes down, my application does not get a error return value after attempting a 'send' call. I am using a single non-blocking socket instance. The thread checks for a 'recv' each loop using 'select'. It does eventually get an error on 'recv' but never on 'send'.
When the remote PC has a internet connectivity loss it will cause the program to be disconnected from the server for minutes to hours before it recognises the connection loss happened and switches to re-login the server. What can be done to help detect the hard disconnect?
void checkConnect(NTRIP& server)
{
//1st check for recv or gracefully closed socket
char databuf[SERIAL_BUFFERSIZE];
fd_set Reader, Writer, Err;
TIMEVAL Timeout;
Timeout.tv_sec = 1; // timeout after 1 seconds
Timeout.tv_usec = 0;
FD_ZERO(&Reader);
FD_ZERO(&Err);
FD_SET(server.socket, &Reader);
FD_SET(server.socket, &Err);
int iResult = select(0, &Reader, NULL, &Err, &Timeout);
if(iResult > 0)
{
if(FD_ISSET(server.socket, &Reader) )
{
int recvBytes = recv(server.socket, databuf, sizeof(databuf), 0);
if(recvBytes == SOCKET_ERROR)
{
cout << "socket error on receive call from server " << WSAGetLastError() << endl;
closesocket(server.socket);
server.connected_IP = false;
}
else if(recvBytes == 0)
{
cout << "server closed the connection gracefully" << endl;
closesocket(server.socket);
server.connected_IP = false;
}
else //>0 bytes were received so read data if needed
{
}
}
if(FD_ISSET(server.socket, &Err))
{
cout << "select returned socket in error state" << endl;
closesocket(server.socket);
server.connected_IP = false;
}
}
else if(iResult == SOCKET_ERROR)
{
cout << "ip thread select socket error " << WSAGetLastError() << endl;
closesocket(server.socket);
server.connected_IP = false;
}
//2nd check hard disconnect if no other data has been sent recently
if(server.connected_IP == true && getTimePrecise() - server.lastDataSendTime > 5.0)
{
char buf1[] = "hello";
cout << "checking send for error" << endl;
iResult = send(server_main.socket, buf1, sizeof(buf1), 0);
if(iResult == SOCKET_ERROR)
{
int lasterror = WSAGetLastError();
if(lasterror == WSAEWOULDBLOCK)
{
cout << "server send WSAEWOULDBLOCK" << endl;
}
if(lasterror != WSAEWOULDBLOCK)
{
cout << "server testing connection send function error " << lasterror << endl;
closesocket(server.socket);
server.connected_IP = false;
}
}
else
{
cout << "sent out " << iResult << " bytes" << endl;
}
server.lastDataSendTime = getTimePrecise();
}
}
It is not possible to detect disconnect until you try to send something.
The solution for you is the following:
You detect that you have received no data for a certain period of time and you want to check is the connection is alive.
You send some data to the server using send function. It could be protocol-specific ping packet or either garbage. The send function returns immediately, because it does not wait for actual data send. It only fills internal send buffer.
You begin waiting for socket read.
While you are waiting, OS tries to send the data in the send buffer to the server.
When OS detects that it cannot deliver data to the server, then the connection is marked as erroneous.
Now you will get an error when calling recv and send functions.
The send timeout is system specific and can be configured. Usually, it is about 20 seconds (Linux) - 2 minutes (Windows). It means that you need to wait a lot before you receive an error.
Notes:
You can also turn on TCP keep alive mechanism, but I don't recommend you to do this.
You can also modify TCP timeout intervals. It can be helpful when you want the connection to survive the temporary network disconnect.
That's how TCP works and is intended to work. You will get an error from a subsequent send, but never from the first send after the disconnect. There is buffering, and retry, and retry timeout to overcome before an error is signalled.
I have two applications which work like a TCP client/server.
First application is the client which uses OpenCV to detect and send commands via TCP to the Server which controls a mobile robot.
My applications work well if I'm in my developing computer, but when I test it in real world with my robot, i realize that I have some delays with the data exchanged between client and server.
This happens because the computer where iItest the applications is a little bit slow compared to my developing computer which is faster and give no problems. In real world case, server doesn't receive packets from client in real time so it execute the operations with a delay.
So, the problem is when the client loose the detection and send commands to the server in order to stop it. The server receives packets with a delay so when clients sends stop (heading = 0, distance = 0, nodetection) server doesn't receive the command immediately because it is receiving previous command packets and so it stop only after few meters.
I'd like to find a solution in order to stop immediately the server and discard all the packages about the moving information because they are useless if the robot has to stop.
In order to stop the robot I send a nodetecting package which unfortunately is not received in real time so the robot continue to move for a while.
(I'm doing this test on the same machine, so I connect on localhost)
At the moment, client uses this code:
while (key_mode!='q')
{
//wait and error processing
context.WaitAnyUpdateAll();
// obtain al the metadata image,depthmap and scene
Mat frame = getImageFromKinect();
// do detection and tracking
switch(mode)
{
..
case ROBOT_CONTROL:
{
// Connect to the server
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(tcp::v4(), server, boost::lexical_cast<string>(porta));
tcp::resolver::iterator iterator = resolver.resolve(query);
tcp::socket s(io_service);
try
{
s.connect(*iterator);
}
catch (boost::system::system_error const& e)
{
std::cout << "Warning: could not connect to the server\n" << e.what() << "\nPossible Solution: try to check is Server is UP\n" << std::endl;
}
..
..
float delta = heading - last_heading;
if (!is_equal(delta, 0.0)){
// heading_data = send_heading + token + boost::lexical_cast<std::string>(delta);
// heading_length = strlen(heading_data.c_str());
try
{
// boost::asio::write(s, boost::asio::buffer(heading_data, heading_length));
}
catch (boost::system::system_error const& e)
{
std::cout << "Warning: could not send commands : " << e.what() << std::endl;
}
}
last_heading = heading; // store current for next subtraction
#endif
#if 1
heading_scalato = heading / 3.0;
heading_data = send_heading + token + boost::lexical_cast<std::string>(heading_scalato);
heading_length = strlen(heading_data.c_str());
try
{
boost::asio::write(s, boost::asio::buffer(heading_data, heading_length));
}
catch (boost::system::system_error const& e)
{
std::cout << "Warning: could not send commands : " << e.what() << std::endl;
}
#endif
distance_data = send_distance + token + boost::lexical_cast<std::string>(distance);
distance_length = strlen(distance_data.c_str());
try
{
boost::asio::write(s, boost::asio::buffer(distance_data, distance_length));
}
catch (boost::system::system_error const& e)
{
std::cout << "Warning: could not connect : " << e.what() << std::endl;
}
..
..
// if it has to stop:
else
{
// stop rover
//control.setHeading(0.0);
//control.setDistance(0.0);
float heading = 0.0;
float distance = 0.0;
heading_data = send_heading + token + boost::lexical_cast<std::string>(heading);
distance_data = send_distance + token + boost::lexical_cast<std::string>(distance);
heading_length = heading_data.size();//strlen(heading_data.c_str());
distance_length = strlen(distance_data.c_str());
try
{
boost::asio::write(s, boost::asio::buffer(heading_data, heading_length));
boost::asio::write(s, boost::asio::buffer(distance_data, distance_length));
}
catch (boost::system::system_error const& e)
{
std::cout << "Warning: could not send commands : " << e.what() << std::endl;
}
// write info on image
char text[100];
sprintf(text,"ROBOT CONTROL: No detection");
putText(hogResultFrame,text,Point(4,89),FONT_HERSHEY_PLAIN,1,Scalar(0,0,0));
putText(hogResultFrame,text,Point(5,90),FONT_HERSHEY_PLAIN,1,Scalar(100,100,255));
nodetection_length = nodetection.size();
try
{
boost::asio::write(s, boost::asio::buffer(nodetection, nodetection_length));
}
catch (boost::system::system_error const& e)
{
std::cout << "Warning: could not send commands : " << e.what() << std::endl;
}
In server, i use:
void* runThread(void*)
{
while(Aria::getRunning())
{
if(start_routine){
if(temp_heading < 0.0){
printf("\n\nStarting Discovering routine, then sleeping 3 seconds.\a\n\n");
robot.setRotVel(5.0);
ArUtil::sleep(3000);
temp_heading = -1;
}
else if(temp_heading >= 0.0) {
printf("\n\nStarting Clockwise Discovering routine, then sleeping 3 seconds.\a\n\n");
robot.setRotVel(-5.0);
ArUtil::sleep(3000);
temp_heading = 1;
}
}
if( !flag_heading && !flag_distance)
{
myMutex.lock();
temp_heading=m_heading;
temp_distance=m_distance;
myMutex.unlock();
if (is_equal(temp_heading, 0.0)){
robot.setRotVel(0.0);
}
else robot.setRotVel(-ArMath::radToDeg(temp_heading));
if(temp_distance <= distanza_minima || is_equal(temp_distance, 0.0))
robot.setVel(0.0);
else
robot.setVel(float(temp_distance/20));
printf("runThread:: heading= %f distance = %f rob_vel = %f rob_rot_vel = %f\n",ArMath::radToDeg(temp_heading),temp_distance, robot.getVel(),robot.getRotVel());
flag_heading = true;
flag_distance = true;
start_routine = false;
}
ArUtil::sleep(100);
}
}
DataLine GetValueFromLine(const std::string& sData) {
std::string sName, sInteger;
std::stringstream ss;
DataLine Result;
size_t sz = sData.find('#');
sName = sData.substr(0,sz); // Just in case you need it later
Result.sName = sName;
sInteger = sData.substr(sz + 1,sData.length() - sz);
ss.str(sInteger);
ss >> Result.nNumber;
if (ss.fail()) {
// something went wrong, probably not an integer
}
return Result;
}
void session(socket_ptr sock)
{
try
{
for (;;)
{
char data[max_length];
boost::system::error_code error;
size_t length = sock->read_some(boost::asio::buffer(data), error);
data[length] = 0;
if (error == boost::asio::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw boost::system::system_error(error); // Some other error.
output = GetValueFromLine(data);
std::cout << "*******************\n";
comando = output.sName;
valore = output.nNumber;
if (output.sName == "nodetection"){
start_routine = true;
std::cout << "\nSto ricevendo: " << output.sName;
}
else if (output.sName == "heading"){
start_routine = false;
control.setHeading(output.nNumber);
std::cout << "\nSto ricevendo: " << output.sName << "e heading: " << output.nNumber;
}
else if (output.sName == "distance"){
start_routine = false;
control.setDistance(output.nNumber);
std::cout << "\nSto ricevendo: " << output.sName << "e distance: " << output.nNumber;
}
// boost::asio::write(*sock, boost::asio::buffer(data, length));
}
}
catch (std::exception& e)
{
std::cerr << "Exception in thread: " << e.what() << "\n";
}
}
void server(boost::asio::io_service& io_service, short port)
{
tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port));
for (;;)
{
socket_ptr sock(new tcp::socket(io_service));
a.accept(*sock);
boost::thread t(boost::bind(session, sock));
}
}
int main(int argc, char **argv)
{
// control server initialitation..
....
boost::asio::io_service io_service;
server(io_service, porta);
return 0;
}
I was thinking to force the client to close the TCP connection when it reaches a no detecting condition in order to force the server to reject the pending packets, but how I can do this?
How to destroy s pointer in boost?
Are there any other solutions?
If I close the connection, does the server reject the pending packets?
As I understand your problem, you have a message that you intend your application to abandon all current processing and flush the input queue. However, because the application is busy receiving and processing previous messages, it does not receive the abandon and flush message until all previous messages are processed - which makes abandon and flush a no operation
IMHO you need to design and code a multithreaded application.
One thread, as light weight as possible, reads the incoming messages as fast as possible and quickly checks for the abandon and flush message. If the message is OK, then it is added to a queue and the next message is checked.
The second thread pulls the messages from the queue where the messages are stored by the first thread and processes them, perhaps taking a long time to do so. From time time it checks for an abandon and flush signal from the first thread.
Another approach to consider: the application that sends the messages maintains the queue. When the application which receives the messages finishes processing a message, it sends a request for the next message. The sender only sends messages when requested. If the abandon and flush condition arises, the application sending the messages looks after this. The application receiving the messages only has to deal with one at a time. This approach greatly simplify the message receiver, at the cost of complexity in the sending application, a more elaborate communications protocol and, possibly, a reduction in maximum throughput.