How Do I Send Data From One Computer To Another Without A Server (in C++)? - c++

so I want to send an int32 (or any 4 bytes data) from one pc to another, the size of the data will always be the same, I don't need any checking to see if both pcs are online or any disconnect function, if pc2 didn't receive the data or he went offline, I just want pc1 to send the data, if pc2 is offline nothing happens and if it's online it store it somewhere.
Most tutorials I've found uses a server way of connecting, so there are 3 pcs, 2 clients and 1 server, client1 sends data to the server and the server sends it to client2, but is there a way to send it directly to client2, as if client2 is the server?

There are two common protocols used to send raw data over an ip based network. They are called TCP and UDP and serve slightly different approaches.
TCP is connection oriented and relies heavily on the server client model. On host acts as a server and accepts incoming requests on a predefined socekt. After the TCP connection is setup, you have a duplex (two-way) stream that you can use to exchange data.
UDP is a packet oriented protocol. One host (usually called the server) listens to imcoming packets and can answer them. No real "connection" is established tough.
You probably want to use UDP. Note that altough this protocol does not establish a connecion, there still needs to be at least one host, that is waiting for incoming data on a predefined port. This one is usually called the "server". However also the client can bind its UDP socket to a specific port and thus can act as a "client" and a "server" during the same time.
You can setup both hosts to listen and send on/to the same preefined port number and achieve a connectionless packetoriented way to exchange data. That way both hosts act as server and client simultaneously.
How you actually implement this, depends on your operating system. On Linux (and other POSIX compatible OSes) you can use standard UDP sockets, on Windows there is some equivalent API. Either way I suggest you to first follow a tutorial on how to program a standard TCP server and client, as most of the operations on the sockets are similar (create the socket, bind it to an address:port, and read/write data from it).

Related

boost::asio::tcp two-way communication on a socket

I am using boost::asio, TCP communication and C++ to create a client and a server that talk over a TCP socket. I need both the client and the server to be able send and receive data to each other. I am able to make them communicate over a socket where the server is continuously sending some data and the client is continuously reading on the socket. It works.
Now for the other way communication : For client to send some data and the server to be able to read it, can I use the same socket for this? Or Do I need to use a separate socket? Is it possible to read and write on the same socket for two applications communicating over TCP?
A boost::asio based example to illustrate this will be great if available. But I am able to find examples which are about only one-way communications.
For client to send some data & server to be able to read it, can I use the same socket for this? Or Do I need to use a separate socket ? Is it possible to read and write on the same socket for two applications communicating over TCP ?
Yes. TCP is full duplex. Applications define the protocol of what/how messages are exchanged between client and server. Weather they do asynchronously or synchronously, TCP doesn't care.
The client server paradigm in tcp is one where the client initiates the connection and the server listens for incoming connections. Once tge connection is established, it is up to higher layer protocol like http to establish how data is exchanged. As far as tcp is concerned both client and server may send or receive data any way they choose. Tcp is full duplex.

Sharing sockets (WINSOCK) by sending them to each other between 2 servers

I am trying to write a distributed server system (consisting of server 1="main", and server 2="replacement" for now). Don't mind some dirty methods, it's just to achieve a basic function a distributed server would achive.
Currently I have both servers running via SO_REUSEADDR and a TCP Socket (maybe UDP will solve my problem, but I wanna try it either way with TCP first) on the same machine.
Main server sends establishes a connection with the Replacement server and clients connecting to it.
Now what I want to achieve: The main server should send the socket of the connecting clients to the replacement server, so in case the main server can't work anymore (timeout or what ever) the replacement server can work with the clients and send/recv with them.
The socket I send from main to the replacement server is the one I get with ClientSocket = ::accept(ListenSocket, NULL, NULL); where ClientSocket is a SOCKET (UINT_PTR).
The replacement server can't send/recv to the clients even though the main server gets terminated midway.
Is that because each server, even though they run on the same port, need to be connected via a ::connect from the clients?
EDIT: If my theory is true, this should be solved by using UDP instead of TCP as well, no?
EDIT2: With distributed server I mean a server which in case of a failure will be replaced by another without the clients task getting interrupted.
EDIT3: If there is a better and more simple way to do this, I'd like to know about that as well. I'm not too fond of sockets and server communication as of now that's how I came up with my idea to solve it.
You cannot send a socket between machines. A socket is an OS concept. It represents (in this case) a connection between the server and a client. This connection cannot be resumed on a different machine that has a different IP address because a TCP connection is defined to be established between a pair of addresses and a pair of ports.
The UINT_PTR on one machine means nothing to another machine. It is an opaque value. It is an OS handle.
UDP does not solve the problem since the client needs to notice that the IP address is is communicating with has changed.
Even if you manage that you have the problem that a server failure kills all data on that server. The other server cannot resume with the exact same data. This is a basic problem of distributed computing. You cannot keep the state of all three machines completely in sync.
Make the clients tolerate interruptions by retrying. Make the servers stateless and put all data into a database.
This is a very hard problem to solve. Seek off-the-shelve solutions.

Manually specify which network interface to send data

I have implemented a service which sends and receives data over a tcp socket. Now there are two network interfaces on my machine, which I'm supposed to run the service over two networks.
How can I specify which network interface to send data? (Using Boost::asio or traditional Berkeley sockets, or by using a system call to change kernel's routing table on the fly)
I don't know about Boost, but in general if you want to send/recv using a specific interface than you need to bind() the socket to that interface's IP address, or alternatively on some platforms you can use setsockopt(SOL_SOCKET, SO_BINDTODEVICE) instead.
Did you tried this, create a socket bind to 0.0.0.0 for receiving packet from all interfaces. Then create one socket for each interface for sending packet. Key thing here is to set REUSEADDRSS option so that socket for sending can bind to address per-interface and sharing the same port of the one receiving packet.
If you are dealing with TCP, an established connection will ready bind to a specific interface. You won't be able to send to that connection by other interfaces.

How to find the destination address of a UDP packet using boost::asio?

I'm developing a peer-to-peer communications network for use over a LAN in an industrial environment. Some messages are are just asynchronous, and don't require a response. Others are request-response. The request messages (and the async messages) are sent to a multicast group, and the replies to requests are sent unicast. Each endpoint, therefore, receives UDP packets that are sent to the multicast group, and also receives messages that are just sent to it using plain unicast.
So far it's working fine, but there doesn't seem to be any way in boost::asio to find out the destination address of a received UDP packet (using socket.async_receive_from) - whether it was sent to the multicast group or the actual interface. I can use the contents of the message to infer whether it was sent multicast or unicast, but it would be nice to be able to also check the destination address.
We are currently using Windows 7, but will be transitioning to Linux in the future.
Is there a way to find the destination address of a UDP packet received using boost::asio?
Unfortunately this is not possible with boost::asio, and usually is not "the way to do" it, as you try to access Transport Layer information at the Application Layer.
So you basically have two options:
a) Write non-portable system code with for example IP_PKTINFO or SO_BINDTODEVICE on Linux. Example Code can be found on the boost asio mailing list here
b) use two distinct sockets, one for the multicast and one for the unicast. You therefore need to specify a listen_address other than "0.0.0.0" on each socket.
udp::endpoint(address_v4::from_string("239.192.152.143"), 6771)
This Question on SO might also be helpful: Using a specific network interface for a socket in windows

Send same packets to multiple clients

I have to develop a software to send same packets to multiple destination.
But i must not use multicast scheme.!!!! ( because my boss is a stupid man )
so, any way, the problem is that:
i have same packets and multiple IP address ( clients) and i can not use multicast
how can i do that in the best way?
i must use c++ as a language and Linux as a platform.
so please help me
Thanx
If your boss said you can't use multicast, maybe he/she has his/her reason. I guess broadcasting is out of the game too?
If these are the requisites, your only chance is to establish a TCP connection with every remote host you want to send packet to.
EDIT
UDP, conversely, would not provide much benefit over multicasting if your application will run over a LAN you are in charge for configuration of, that's the reason I specified TCP.
Maybe you have to describe your scenario a little better.
This could be done with either TCP or UDP depending on your reliability requirements. Can you tolerate lost or reordered packets? Are you prepared to handle timeouts and retransmission? If both answers are "yes", pick UDP. Otherwise stay with TCP. Then:
TCP case. Instead of single multicast UDP socket you would have a number of TCP sockets, one per destination. You will have to figure out the best scheme for connection establishment. Regular listening and accepting connecting clients works as usual. Then you just iterate over connected sockets and send your data to each one.
UDP case. This could be done with single UDP socket on the server side. If you know the IPs and ports of the clients (data receivers) use sendto(2) on the same data for each address/port. The clients would have to be recv(2)-ing at that time. If you don't know your clients upfront you'd need to devise a scheme for clients to request the data, or just register with the server. That's where recvfrom(2) is usefull - it gives you the address of the client.
You have restricted yourself by saying no to multicast. I guess sending packets to multiple clients is just a part of your requirement and unless you throw more light, it will be difficult to provide a complete solution.
Are you expecting two way communication between the client and the server ? in that case choosing multicast may prove complex. please clarify
You have to iterate through the clients and send packets one after another. You may want to persist the sessions if you are expecting response from the clients back.
Choice of UDP or TCP again depends on the nature of data being sent. with UDP you would need to handle out of sequence packets and also need to implement re-transmission.
You'll have to create a TCP Listerner on your server running at a particular port listening for incoming Tcp Client connections (Sockets).
Every time a client connects, you'll have to cache it in some kind of datastructre like a Name value pair (name being a unique name for the client amd value being the Network Stream of that client obtained as a result of the TCP socket).
Then when you are finally ready to transmit the data you could either iterate through this collection of name value pair connections and send them data as byte array one by one to each client or spawm off one thread per connected client and have it send the data concurrently.
TCP is a bulky protocol (due to its connection-oriented nature) and transmission of large data (like videos/images) can be quite slow.
UDP is definitely the choice for streaming large data packets but you'll have to trade-off with the delivery gurantee.