I am trying to make a simple server.
A language I am restricted to use is c++.
I am using ZeroMQ.
I have creatred a simple server and a client, as in documentation.
ZeroMQ uses TCP instead of HTTP.
I know that HTTP's underlying layer is TCP, so I want to know will it have any performance issues by using TCP instead of HTTP.
And for HTTP I can use curl to test the application.
What should I use for TCP ( curl command to send request to a socket with a string parameter ).
Server:
#include <zmq.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
int main (void)
{ // Socket to talk to clients
void *context = zmq_ctx_new ();
void *responder = zmq_socket (context, ZMQ_REP);
int rc = zmq_bind (responder, "tcp://*:5555");
assert (rc == 0);
while (1)
{
char buffer [10];
zmq_recv (responder, buffer, 10, 0);
printf ("Received Hello\n");
// trying to send json object
zmq_send (responder, "World", 5, 0);
// zmq_send (responder, "World", 5, 0);
sleep (1); // Do some 'work'
}
return 0;
}
client:
// Hello World client
// Connects REQ socket to tcp://localhost:5555
// Sends "Hello" to server, expects "World" back
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int main (void)
{
void *context = zmq_ctx_new ();
// Socket to talk to server
printf ("Connecting to hello world server...\n");
void *requester = zmq_socket (context, ZMQ_REQ);
zmq_connect (requester, "tcp://localhost:5555");
int request_nbr;
for (request_nbr = 0; request_nbr != 10; request_nbr++)
{
zmq_msg_t request;
zmq_msg_init_size (&request, 5);
memcpy (zmq_msg_data (&request), "Hello", 5);
printf ("Sending Hello %d...\n", request_nbr);
zmq_msg_send (&request, requester, 0);
zmq_msg_close (&request);
zmq_msg_t reply;
zmq_msg_init (&reply);
zmq_msg_recv (&reply, requester, 0);
printf ("Received World %d\n", request_nbr);
zmq_msg_close (&reply);
}
zmq_close (requester);
zmq_ctx_destroy (context);
return 0;
}
Q1: will it have any performance issues by using TCP instead of HTTP?
A1: yes, it will. Both performance and latency will benefit from avoiding HTTP-rich-re-wrapping of data
Q2: What should I use for TCP to send a request to a socket with a string parameter?
A2: No command ( curl command ) will help you. ZeroMQ uses certain line-code ( assume it as a trivial protocol between communicationg peers ), so a standalone command-line tool will not be able to match the line-code requirement off-the-shelf. Solution? Create a simple c-programme, that will consume a cmd-line arguments ( the string, as an example ) and assemble a ZeroMQ-layer compatible data-framing so as to communicate with the remote peer. Also you shall notice, that for ZeroMQ REQ/REP Formal Communication Pattern to work, this proxy-tool will have to become the sole respective REQ, resp. REP entity in the step-forward-locking diadic-communication relation, thus also providing an awaited response, the REQ-side is expecting to receive after the REP-side has received a message.
Related
I have implemented a websocket server in a QCoreApplication. As soon as a connection is established with a client, I wish to send a series of messages to it immediately in real-time with a delay of 0.5 seconds between messages. However, the individual messages reach the client only after all the messages have been sent or right after sendMyMessages() method returns in the below implementation of my websocket server. If I have a huge number of messages to send, the client has to wait for a long time before getting all the messages in one go.
MyWebSocketServer.h
#ifndef MYWEBSOCKETSERVER_H
#define MYWEBSOCKETSERVER_H
#include <QtCore/QObject>
#include <QtCore/QList>
#include <QtCore/QByteArray>
QT_FORWARD_DECLARE_CLASS(QWebSocketServer)
QT_FORWARD_DECLARE_CLASS(QWebSocket)
class MyWebSocketServer : public QObject
{
Q_OBJECT
public:
explicit MyWebSocketServer(quint16 port,
bool debug = false,
QObject *parent = nullptr);
~MyWebSocketServer();
Q_SIGNALS:
void closed();
private Q_SLOTS:
void onNewConnection();
void socketDisconnected();
private:
void sendMyMessages(QWebSocket *client);
QWebSocketServer *m_pWebSocketServer;
QList<QWebSocket *> m_clients;
bool m_debug;
};
#endif // MYWEBSOCKETSERVER_H
MyWebSocketServer.cpp
#include "MyWebSocketServer.h"
#include <iostream>
#include <fstream>
#include <chrono>
#include <thread>
#include <QtWebSockets/qwebsocketserver.h>
#include <QtWebSockets/qwebsocket.h>
#include <QtCore/QDebug>
QT_USE_NAMESPACE
MyWebSocketServer::MyWebSocketServer(quint16 port,
bool debug,
QObject *parent)
: QObject(parent)
, m_pWebSocketServer(new QWebSocketServer(
QStringLiteral("My WebSocket Server"),
QWebSocketServer::NonSecureMode,
this))
, m_debug(debug)
{
connect(m_pWebSocketServer,
&QWebSocketServer::newConnection,
this,
&MyWebSocketServer::onNewConnection);
connect(m_pWebSocketServer,
&QWebSocketServer::closed,
this,
&MyWebSocketServer::closed);
m_pWebSocketServer->listen(QHostAddress::LocalHost, port);
}
MyWebSocketServer::~MyWebSocketServer()
{
m_pWebSocketServer->close();
qDeleteAll(m_clients.begin(), m_clients.end());
}
void MyWebSocketServer::onNewConnection()
{
QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();
connect(pSocket,
&QWebSocket::disconnected,
this,
&MyWebSocketServer::socketDisconnected);
m_clients << pSocket;
sendMyMessages(pSocket);
}
void MyWebSocketServer::sendMyMessages(QWebSocket *client)
{
std::fstream jsonStringFileHandler;
jsonStringFileHandler.open("my-messages.txt", std::ios::in);
if (jsonStringFileHandler.is_open())
{
std::string message;
while(getline(jsonStringFileHandler, message))
{
// Individual messages don't go through immediately
// Only after this method returns, all the messages show up on the client's end
// Is it possible to send the individual messages immediately? (probably with a 0.5 second delay)
client->sendTextMessage(QString::fromUtf8(message.c_str()));
}
jsonStringFileHandler.close();
}
}
void MyWebSocketServer::socketDisconnected()
{
QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
if (pClient)
{
m_clients.removeAll(pClient);
pClient->deleteLater();
}
}
Only after the sendMyMessages() returns, the client gets all the messages. It is not in real-time. I understand it would be possible to achieve what I am after using some asynchronous programming technique but I unable to figure out a way to set it up in my implementation of the websocket server.
Here is an implementation of the websocket server that worked for me in Python using the websockets and asyncio modules. However, I wish to implement the same logic in C++ using Qt.
import asyncio
import websockets
async def sendMyMessages(websocket, path):
with open("my-messages.txt") as fp:
lines = fp.readlines()
for line in lines:
await asyncio.sleep(0.5)
await websocket.send(line.strip())
start_server = websockets.serve(sendMyMessages, "127.0.0.1", 3000)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
One of the approaches I found uses QWebSocket::flush() immediately after a call to QWebSocket::sendTextMessage().
From the docs on QWebSocket::flush(),
This function writes as much as possible from the internal write buffer to the underlying network socket, without blocking. If any data was written, this function returns true; otherwise false is returned. Call this function if you need QWebSocket to start sending buffered data immediately. The number of bytes successfully written depends on the operating system. In most cases, you do not need to call this function, because QWebSocket will start sending data automatically once control goes back to the event loop.
However, I am not sure if this is the right approach as the doc indicates that the data may not be written to the underlying network socket reliably. I will be happy to know if there is a better technique out there!
client->sendTextMessage(QString::fromUtf8(message.c_str()));
client->flush();
std::this_thread::sleep_for(std::chrono::milliseconds(50));
I've got an application where I will be using a standalone C programming to read a CAN bus port with a socket. The user interface on this is Qt/QML code. I would like to use a non-blocking approach to call the bin program and either return nothing or return a string of the CAN packet.
The application will be low speed (just monitoring key presses, etc) so speed is not an issue. The current approach involves writing data from the socket program to a file, then having ANOTHER C program take the file and echo the string back to QML. UGH! Seems very messy. A simple Go/NoGo call would be easier. Here's the code I've got so far.
Thanks for any comments.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
// Returns 0 if no errors, > 0 if errors found
int main(void) {
struct ifreq ifr;
struct can_frame frame;
struct sockaddr_can addr;
int s; // CAN socket descriptor
int nbytes; // Number of bytes read from CAN socket
char run_daemon = 0; // Set to 1 to run as a daemon process
char show_errors = 0; // Set to 1 to print errors
char *ifname = "can0"; // Define the CAN driver for use
if (run_daemon) // Skip the daemon call if not enabled
daemon(1,1);
if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
if (show_errors)
perror("Error while opening RAW socket");
return 1;
}
strcpy (ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
if (show_errors)
perror("Error in socket bind");
return 2;
}
// Loop here for daemon process
while (1) {
// Read CAN frame data
nbytes = read(s, &frame, sizeof(struct can_frame));
// If data is ready, process it
if (nbytes > 0) {
// Print all relevent frame data to QML
printf("%d ",frame.can_id);
printf("%d ",frame.can_dlc);
if(frame.can_dlc>0) printf("%d ",frame.data[0]);
if(frame.can_dlc>1) printf("%d ",frame.data[1]);
if(frame.can_dlc>2) printf("%d ",frame.data[2]);
if(frame.can_dlc>3) printf("%d ",frame.data[3]);
if(frame.can_dlc>4) printf("%d ",frame.data[4]);
if(frame.can_dlc>5) printf("%d ",frame.data[5]);
if(frame.can_dlc>6) printf("%d ",frame.data[6]);
if(frame.can_dlc>7) printf("%d ",frame.data[7]);
printf("\n");
}
if (!run_daemon) { // Exit if daemon is not running
close(s); // Close the CAN socket
return 0;
}
}
return 0; // Should never get here !!!
}
The code that I have posted below, is basically used to get (continuous streaming data) from a software and display that data as it is received. The issue that I am facing is, that the software (which already has the "server") is on Windows, but I need to get the data on a separate system running Linux (Ubuntu).
Can anyone guide me regarding what changes do I need to make to the code in-order to make it work on Linux?
Also since they are "communicating" over a network, will there be any changes in the code to point to the server on the windows machine? ( I am sorry for such terminology, I am a bit new to this, so please correct me if I am mistaken)
#include "vrpn_Connection.h" // Missing this file? Get the latest VRPN distro at
#include "vrpn_Tracker.h" // ftp://ftp.cs.unc.edu/pub/packages/GRIP/vrpn
#include "conio.h" // for kbhit()
//== Callback prototype ==--
void VRPN_CALLBACK handle_pos (void *, const vrpn_TRACKERCB t);
//== Main entry point ==--
int main(int argc, char* argv[])
{
vrpn_Connection *connection;
char connectionName[128];
int port = 3883;
sprintf(connectionName,"localhost:%d", port);
connection = vrpn_get_connection_by_name(connectionName);
vrpn_Tracker_Remote *tracker = new vrpn_Tracker_Remote("Tracker", connection);
tracker->register_change_handler(NULL, handle_pos);
while(!kbhit())
{
tracker->mainloop();
connection->mainloop();
Sleep(5);
}
return 0;
}
//== Position/Orientation Callback ==--
void VRPN_CALLBACK handle_pos (void *, const vrpn_TRACKERCB t)
{
printf("Tracker Position:(%.4f,%.4f,%.4f) Orientation:(%.2f,%.2f,%.2f,%.2f)\n",
t.pos[0], t.pos[1], t.pos[2],
t.quat[0], t.quat[1], t.quat[2], t.quat[3]);
}
I would appreciate if anyone could suggest an "easier" alternate to this as well. Thank you!
kbhit() and Sleep() functions are exclusive to Windows.
Here you don't really need kbhit function. You can use an infinite loop instead.
For the sleep method, you can use this code from this thread :
Sleep function in C++
#ifdef _WIN32
#include <windows.h>
void sleep(unsigned milliseconds)
{
Sleep(milliseconds);
}
#else
#include <unistd.h>
void sleep(unsigned milliseconds)
{
usleep(milliseconds * 1000); // takes microseconds
}
#endif
But a much simpler method is to use boost::this_thread::sleep.
This code should work on Linux and Windows.
//...
while(1)
{
tracker->mainloop();
connection->mainloop();
sleep(5000);
}
//...
I have to write lkm, which would resend all incoming packets. Yep, I know about xt_TEE, but have to write it on my own. I've looked through some examples: http://www.phrack.org/archives/55/p55_0x0c_Building%20Into%20The%20Linux%20Network%20Layer_by_lifeline%20&%20kossak.txt (it's rather old) and http://www.xakep.ru/post/20794/default.asp?print=true (packet sniffer).
Then I've wrote my code:
//INCLUDES//////////////////////////////////////////////////////////////
#include <linux/ip.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/module.h>
#include <linux/kernel.h>
//ABOUT/////////////////////////////////////////////////////////////////
MODULE_AUTHOR("");
MODULE_DESCRIPTION("");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.0.1");
//DEFINES///////////////////////////////////////////////////////////////
//SYSCALLS//////////////////////////////////////////////////////////////
//PROTOTYPES/////////////////////////////////////////////////////////////
int new_hook_func(struct sk_buff *skb, struct device *dv, struct packet_type *pt);
void test();
//GLOBALS///////////////////////////////////////////////////////////////
static struct packet_type my_packet_type;
static char *dev = "eth0";
struct net_dev *d;
//INIT//////////////////////////////////////////////////////////////////
static int __init init(void)
{
printk(KERN_ALERT "module init\n");
d = dev_get_by_name(&init_net, dev);
my_packet_type.type = htons(ETH_P_ALL);
my_packet_type.func = new_hook_func;
my_packet_type.dev = d;
dev_add_pack(&my_packet_type);
return 0;
}
//EXIT//////////////////////////////////////////////////////////////////
static void __exit exit(void)
{
dev_remove_pack(&my_packet_type);
printk(KERN_ALERT "module exit");
}
////////////////////////////////////////////////////////////////////////
module_init(init);
module_exit(exit);
////////////////////////////////////////////////////////////////////////
//CORE//////////////////////////////////////////////////////////////////
int new_hook_func(struct sk_buff *skb, struct device *dv, struct packet_type *pt)
{
struct iphdr *ip;
ip = (struct iphdr*)skb_network_header(skb);
if(skb->pkt_type != PACKET_OUTGOING)
{
if(ip->version == 4 && ip->protocol == IPPROTO_ICMP)
{
struct sk_buff *my_skb = 0;
//copy incoming skb
my_skb = skb_copy_expand(skb, 16, 16, GFP_ATOMIC);
//get eth header
struct ethhdr *eth = eth_hdr(my_skb);
//push ethernet layer to skb
skb_push(my_skb, ETH_HLEN);
//set packet type to outgoing
skb->pkt_type = PACKET_OUTGOING;
//send skb struct
dev_queue_xmit(my_skb);
//drop all incoming packets
// kfree_skb(my_skb);
// kfree_skb(skb);
}
}
return NET_RX_DROP;
}
This code is supposed to resend every icmp packet recieved.
So, I've faced three problems:
1) Memory leak. Some how it leaks. I tried to comment whole hook func and there was only return, but memory was still leaking.
2) Return codes don't work. It's no matter what I return(NET_RX_DROP/NET_RX_ACCEPT/NF_DROP/NF_ACCEPT/1/0) is still recieves packets and answers to it.
3) Problems with mac-layer. As you may see in my code, I copy skb struct with expansion and have to push 14 bytes of mac-layer there. Otherwise packet will be sent without any mac bytes.
I apologize for my poor english and kindly ask for help.
I have JBoss running on Sun Java 1.5.
From time to time, it unexpectedly shuts down (in orderly fashion).
I suspect some other process is sending it kill or CTRL+C signals.
Is there a way on Unix/Solaris to trace who sent the signal?
On Solaris, you can use a simple dtrace script to find who is killing your process (assuming its name is java, adjust it otherwise):
dtrace -qn '
proc:::signal-send
/ args[1]->pr_fname == "java" /
{
printf("Process %d (%s by UID %d) sending signal %d to java (pid=%d)\n",
pid,execname,uid,arg1,args[1]->pr_pid);
}'
You can use sigaction to determine the source of the signal. pid may be zero as the signal was send from the kernel or via some user interaction (pressing ctrl+c)
#include <signal.h>
#include <string.h>
#include <stdio.h>
static void signal_handler(int sig, siginfo_t *info, void *data) {
printf ("signal: [%d], pid: [%d], uid: [%d]\n", sig,
info->si_pid,
info->si_uid );
}
int main(int argc, char *argv[]) {
struct sigaction sa;
memset ( &sa, '\0', sizeof ( struct sigaction ) );
sa.sa_sigaction = &signal_handler;
sa.sa_flags |= SA_SIGINFO;
sigemptyset ( &sa.sa_mask );
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
while ( 1 ) {
sleep (1);
}
return 0;
}