ZeroMQs router-dealer pattern. How to handle client address? - c++

I use the router-dealer pattern from 0MQ. Now I want to store the client's address. I know that the first message from the client is the address, IP + portno I guess. Or rather recv() from the router socket puts the address in front of a received packet. But how do I handle this address, e.g. printing out or storing it for further outgoing messages? What type is it?

Here's the Guide explanation on this: http://zguide.zeromq.org/page:all#The-Request-Reply-Mechanisms
The ROUTER manages a set of connections, and keeps an 'identity' for each connection, which is a random number, like a handle. It tells you this identity on each message, as a first frame. It's a binary value, so you can't print it as-is.
The DEALER can override the ROUTER's internal identity by telling it, "use this ID" at connection time. That's what the zmq_setsockopt ZMQ_IDENTITY option does. We use this when nodes have some unique, often string, ID that has some meaning to the application.

the first part of the message is the identity of the sender (dealer) what you can set on the dealer side, with the zmq_setsockopt function (before connecting to the router). it's a maximum 255 char long string. if you don't set it, there will be some random unique thing, starting with #0 char.
so it's not the ip+port of your dealer by default, but you can put there that info if you like.

Related

Message to all connected clients(Winsock)(c++)

I have a server, which creates a separate thread for each new client
while ((client_socket = accept(server_socket, (sockaddr*)&client_info, &client_addr_size)))
{
nclients++;
HOSTENT *hst;
hst = gethostbyaddr((char*)&client_info.sin_addr.S_un.S_addr, 4, AF_INET);
printf("+%s [%s] new connect!\n", (hst) ? hst->h_name : "", inet_ntoa(client_info.sin_addr));
PRINTUSERS;
DWORD thID;
CreateThread(NULL, NULL, SexToClient, &client_socket, NULL, &thID);
}
Stream function every n seconds sends a message.(All streams do not do it at the same time).How to send a message to all clients at the same time?(broadcast)
I cant See Streamfunction. Without the corresponding function I cant give a perfect answer. Normally you would send (asynchron) in a for loop to all clients. The System would teen send the Massage to each Client one After Another. If you want to truly send a Massage to multiple clients at the Same time you need to use multicast.
(= sending one package which will arrive at multiple clients.) Unfortunately this is not possible using TCP, since TCP etablishes a (secure) point to point connection between one host and one client. You would have to use UDP. Remember that UDP wont care if the packages will arrive in the right Order, are correct or arrive at all.

Scapy sniffing pakets

I am trying to create filter function that check if the packet is from facebook, this is my code :
def filter_facebook(packet):
return (IP in packet and (packet[IP].src == "www.facebook.com" or packet[IP].dst == "www.facebook.com"))
packets = sniff(count = 5, lfilter = filter_facebook)
now this function block the continuation and not sniff anything when i am entering to facebook.
now this function block the continuation and not sniff anything when i
am entering to facebook.
This is because no packets match your filter and sniff() waits until 5 packets matches it.
First, you can't use "www.facebook.com" as a comparison value with an IP address. You could first sniff DNS traffic to find which addresses are associated with www.facebook.com as suggested here or find it in another way and then filter with these addresses.
Second, it is a good practice to filter with an interface (iface) when sniffing, the one that receive packets from internet in your situation.

Start a service in a LAN; the unknow server address case

This questions are a new attempt to solve a previous question "How to get a list of all valid ip address in a local network using Javascript?" (see How to get a list of all valid ip address in a local network using Javascript? )
In order to avoid the need of test millions of addresses, I wonder if it would be possible following scenario (in this case, forget the JavaScriipt constraint of the initial post, and suppose a more general language, say C++ and a I/O library like Boost Asio):
a) A server "S" wakeup in a LAN to provide some service, say listening in port X, and get a random address (i.e A1 = 192.168.1.35).
b) A client "C", that need the service, wakeup in the same LAN, an get other random address (say A2 = 192.168.1.40).
"C" does not know the "S" address to get the service. So, two questions:
1.- Can "S" and "C" know for themselves its own addresses (A1 and A2)?
2.- Can "C" send a broadcast request to the LAN in the given port X? Some as "Here P2, some one in X?"
Obviously, if "S" is listening in the given port, and can get the message, them can in turn broadcast its own direction; so if "C" is listening, can get the server's address.
Related to my first question, after some digging, the answer is Yes.
See "Winsock Programer's FAQ".
If in Windows, as is my case for the server, there are a complete API named "IP Helper" http://msdn.microsoft.com/en-us/library/aa366073%28VS.85%29.aspx that can serve as well.
Related to the second question, I will try the quick and dirty method exposed, and hope be back with some result.

Server programming in C++

I'd like to make a chatting program using win socket in c/c++. (I am totally newbie.)
The first question is about how to check if the client receives packets from server.
For instance, a server sends "aaaa" to a client.
And if the client doesn't receive packet "aaaa", the server should re-send the packet again.(I think). However, I don't know how to check it out.
Here is my thought blow.
First case.
Server --- "aaaa" ---> Client.
Server will be checking a sort of time waiting confirm msg from the client.
Client --- "I received it" ---> Server.
Server won't re-send the packet.
The other case.
Server --- "aaaa" ---> Client.
Server is waiting for client msg until time out
Server --- "aaaa" ---> Client again.
But these are probably inappropriate.
Look at second case. Server is waiting a msg from client for a while.
And if time's out, server will re-send a packet again.
In this case, client might receive the packet twice.
Second question is how to send unlimited size packet.
A book says packet should have a type, size, and msg.
Following it, I can only send msg with the certain size.
But i want to send msg like 1Mbytes or more.(unlimited)
How to do that?
Anyone have any good link or explain correct logic to me as easy as possible.
Thanks.
Use TCP. Think "messages" at the application level, not packets.
TCP already handles network-level packet data, error checking & resending lost packets. It presents this to the application as a "stream" of bytes, but without necessarily guaranteed delivery (since either end can be forcibly disconnected).
So at the application level, you need to handle Message Receipts & buffering -- with a re-connecting client able to request previous messages, which they hadn't (yet) correctly received.
Here are some data structures:
class or struct Message {
int type; // const MESSAGE.
int messageNumber; // sequentially incrementing.
int size; // 4 bytes, probably signed; allows up to 2GB data.
byte[] data;
}
class or struct Receipt {
int type; // const RECEIPT.
int messageNumber; // last #, successfully received.
}
You may also want a Connect/ Hello and perhaps a Disconnect/ Goodbye handshake.
class Connect {
int type; // const CONNECT.
int lastReceivedMsgNo; // last #, successfully received.
// plus, who they are?
short nameLen;
char[] name;
}
etc.
If you can be really simple & don't need to buffer/ re-send messages to re-connecting clients, it's even simpler.
You could also adopt a "uniform message structure" which had TYPE and SIZE (4-byte int) as the first two fields of every message or handshake. This might help standardize your routines for handling these, at the expense of some redundancy (eg in 'name' field-sizes).
For first part, have a look over TCP.
It provides a ordered and reliable packet transfer. Plus you can have lot of customizations in it by implementing it yourself using UDP.
Broadly, what it does is,
Server:
1. Numbers each packet and sends it
2. Waits for acknowledge of a specific packet number. And then re-transmits the lost packets.
Client:
1. Receives a packet and maintains a buffer (sliding window)
2. It keeps on collecting packets in buffer until the buffer overflows or a wrong sequenced packet arrives. As soon as it happens, the packets with right sequence are 'delivered', and the sequence number of last correct packet is send with acknowledgement.
For second part:
I would use HTTP for it.
With some modifications. Like you should have some very unique indicator to tell client that transmission is complete now, etc

Get socket's IP address before accepting connection C++

I need to get the IP address of a connection to see if it has already connected previously (checking against a list of ips, if it has connected previously but isnt connected anymore, it will say offline). (using nonblocking sockets)
How can I get the IP without first accepting it.
///
case FD_ACCEPT:
int W;
for(W = 0;W <= ListView_GetItemCount(GetDlgItem(HwND,IDC_IPLIST));W++){
So then im just gonna check the IP against the list view to see if it had connected before. If it has, I want to use the same socket number it was using last time.
This is how I'm accepting connections right now
case FD_ACCEPT:
while(Client[F] != NULL)
{
F++;
}
Client[F]=accept(wParam,(LPSOCKADDR)&ServAdr,&AdrLen);
break;
so to break it down...
I want to check incoming connections against an IP list of previous connections. This list will have the IP and whether its online/offline (connected/not connected). If it has connected before I want it to show Online when I accept the new connection, and use the same socket number it used last time instead of using a new one all together. If it hasn't I want it to be added to the list. (the list will have the socket number)
If this doesnt make much sense I'll try and clarify a bit more.
What you are asking for cannot be done with accept(). You do not have access to a connection's information until after it has been accepted and a new SOCKET handle allocated. To get the connection info pre-acceptance, you have to use the callback functionality of WSAAccept() instead.
Either way, there is no way to reuse an existing SOCKET handle for a new connection. Each accepted connection must have its own unique SOCKET handle. You can certainly associate the new connection from a previously-seen IP with an existing slot in your ListView, though.
If by socket number you mean the number returned by accept(), you can't rely on it's value at all. I mean, if the remote host disconnects and connects again the value returned by accept() will most probably be different. It does not make sense to rely on this number.
If by socket number you mean the position in your array, you can assign the value returned by accept() to temporary variable:
SOCKET tmpSock;
sockaddr_in tmpAddr;
int namelen;
typedef struct { /*...*/ } TClient;
TClient Client[MAX_CLIENTS];
/*...*/
tmpSock = accept(/*...*/);
namelen = sizeof(tmpAddr);
getpeername(tmpSock, (sockaddr*)&tmpAddr,&namelen);
/*...*/
//looking for tmpAddr.sin_addr in your list and calculating
//the list position - F
/*...*/
Client[F].Socket = tmpSock;
Client[F].IsConnected = true;
Client[F].Address = tmpAddr.sin_addr;
Have in mind that after the listen() call the OS kernel will accept all incoming connection to the port/local IP set by you. It means that the connect() of remote host will return successfully whether you call accept() or not (provided you have space in listen queue). Calling accept() will only allow you to interact with the socket. It will not change the connection state seen by the remote host.
I'm not sure the is possible nor an efficient specification to achieve what you want. I would either:
Accept any connection and then check the IP address, disconnecting connections which are not in the list
(This probably isn't suitable for you) Configure an upstream firewall, such that only allowed IP addresses are allowed through.
If you bind to a wildcard address (INADDR_ANY), then the IP address used for communication isn't determined until a connection comes in (it will be one from the interface the packets are passing through). The same listening socket can result in accepted connections on more than one IP address.
If you bind to a specific address, then you already know the address you bound to.