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.
Related
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).
I want to write a tcp server and client application, which has several different connections to each other where the client uses the same port number.
So far I understand it, the server has a listener port and when the client calls it, then I get a new socket for this new connection on the server side, when I call
accept();
Right? So on Server side I can identify my connection with this new socket and send data through it.
Now my understanding problem with the client side. There I get my socket when I call
socket(AF_INET, SOCK_STREAM, 0)
so I have only one socket. In the
connect()
I can specify remote adress and so on. So when I understand it correctly I can use one socket to make several connects to different adresses/port pairs to create different connections. Right?
But how can I now see in the Client from which logical connection I receive my data or how can I send it when 2 logical connections use the same local port at the client? On serverside I have 2 sockets when I have 2 accept called but what about the client side? For send and receive I have only one socket handle?
Or do I have to call socket() for each logical connection on the client?
I can specify remote adress and so on. So when I understand it correctly I can use one socket to make several connects to different adresses/port pairs to create different connections. Right?
No. A socket is the combination of IP address plus port number.
Or do I have to call socket() for each logical connection on the client?
Yes.
It seems to me your confusion arises because you think for example that a certain port is used for SMTP connections and a certain port is used for HTTP connections.
Well, that port alone is NOT defining for you a socket to the server. The IP address of the server is changing.
As an example, consider the following scenario:
You want to connection to Stackoverflow:
Your PC – IP1+port 50500 ——– Stackoverflow IP2 + port 80 (standard http port)
That is the combination IP1+50500 = the socket on the client computer and IP2 + port 80 = destination socket on the Stackoverflow server.
Now you want to connect to gnu.org:
your PC – IP1+port 50501 ——–gnu.org IP3 +port 80 (standard http port)
The combination IP1+50501 = the socket on the client computer and IP3 + port 80 = destination socket on the gnu.org server.
Better check out Beej's Network Programming to learn more. It is a must-read for anyone working with sockets.
So when I understand it correctly I can use one socket to make several connects to different adresses/port pairs to create different connections. Right?
No. A TCP socket can only be used once. When its connection has finished, or even if connect() just fails to make a connection, you must close the socket and create a new one if you want to make a new connection.
But how can I now see in the Client from which logical connection I receive my data or how can I send it when 2 logical connections use the same local port at the client?
Every TCP connection will have its own unique socket allocated for it. It is your responsibility to keep track of them.
On serverside I have 2 sockets when I have 2 accept called but what about the client side?
The exact same thing happens on the client side, too. You need to create and connect a separate socket for every TCP connection you make. So, you will have a new pair of socket()/connect() calls for every connection.
For send and receive I have only one socket handle?
No, you will have a separate socket for each connection, just like on the server side.
Or do I have to call socket() for each logical connection on the client?
Yes, and connect(), too.
I will not talk about a specific programming language rather I will give a general answer that is applicable for all:
In networking what you care about is the socket (IP+Port) this should be unique whether it is server/client socket or UDP/TCP socket.
For server sockets you must assign a port. For client sockets usually you do not specifically assign a port but it will be assigned by the operating system automatically. However, you can still assign a port to a client socket manually (e.g. in case some port numbers are blocked by the firewall)
In the server process:
you can get the server socket info and the connected client socket info
In the client process:
you can get the client socket info and the server (you want to connect to) socket info (of course you should know the server socket info previously otherwise how will you connect to it).
You can send/receive from/to client sockets. After the server gets the connected client socket it can send/receive through it. Same for the client side it can send/receive through its socket.
The "socket" abstraction is an unfortunate relic of past network stack design. It mixes two different sorts of objects.
A listening socket on the server has a port, and potentially an IP address of the local interface. However, this can also be 0.0.0.0 when listening on all interfaces.
A connected socket is associated with a TCP connection, and therefore has 4 parameters: {local IP, local port, remote IP, remote port}.
Now on the client side, you typically don't care about local IP or local port, so these are locally assigned on connect. And yes, these local parameters can in fact be reused for multiple connections. Only the 4-tuple of {local IP, local port, remote IP, remote port} needs to be unique. The OS will map that unique tuple to your SOCKET.
But since you need a new 4-tuple for every connection, it also follows you need a new SOCKET on both sides, for every connection, on both client and server.
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.
Dear Stackoverflowers,
I am researching networking a bit and I decided I'd like to create a small and simple networking library with Winsock. (I am using Completion Ports and Overlapped IO though)
As I researched a bit I came to the following steps for a TCP Listener(Correct me if I am wrong):
Create a Listening Socket
Bind it to a port/IP
Listen on it
When a new connection is created, give a seperate Socket for that connection.
Listener continue's to listen, the specific connection is handled as needed.
EDIT: With a 'connection' from here I mean communication between the server and distinct clients.
Though for an UDP Listener we need to make use of WSARecvFrom which returns the IP address at the lpFrom parameter. Now I was wondering the following:
Is it better to make one UDP Socket listen to incoming connections on a specific port with WSARecvFrom and create new sockets for every specific connection? Or could I just use the UDP Socket itself with WSASendTo. Would that cause any performance penalties if one UDP Socket is used for for example 1000 connections? Or would it be the same or even better then creating/duplicating seperate Sockets for each different incoming connection?
Note: If multiple sockets are needed how would you handle sockets listening on the same port or could a client accept UDP from different ports?
Hope you guys can help!
Ps. Extra tips are always welcome!
Unlike TCP, UDP is connection-less, and as such you don't need to create separate sockets for each party. One UDP socket can handle everything. Bind it to a local IP/Port and call WSARecvFrom() once, and when it reports data to your IOCP you can process the data as needed (if another thread if needed) and then call WSARecvFrom() again. Each time new data arrives, you have to look at the reported lpFrom address to know the IP/Port of the sender. And yes, you can use the same UDP socket for sending data to each sender when needed.
Using C++ I create a single UDP socket, supplying both an IPv4 address and port. I run this on Ubuntu and have both a wlan0 and eth0 interface up and running. Apparently something decides that both interfaces should be used, I appreciate that. Sending and receiving using a different interface does create a kind of a pickle (NAT traversal???) for me though. Using Wireshark I can see packages coming in, but my application does not register them.
To clarify:
I have a tracker which will supply me with a peer. The tracker will also contact that peer to send me a message. In order to overcome NAT traversal issues, I will send a puncture message.
The problem now is that the puncture messages is sent over wlan (I am testing locally with two machines), whereas the messages from the peer are coming in over eth.
So, I think the simplest solution would be to simply use one interface. (Or both one socket)
EDIT:
I will try what is mentioned here on specifying a single interface.
#Barmar, pointed out that UDP sockets may change interface when sendto is called with a destination address that would benefit from it.
I am still fuzzy on the reason for my problem though. Can someone explain why this is an issue in the first place?
EDIT2:
The above mentioned solution of forcing one interface for the socket bind did not work. Apparently the sendto method will choose to ignore this and still go for the other interface if it feels that that will work better.
Does anyone know how to make sure that socket sticks to the interface it was assigned to?
If you need to ensure that UDP replies come from the same address that the request was sent to, the solution is to use multiple sockets. You open one socket for each IP of the server (this may be more than one socket per interface, because of interface aliases), and bind the socket to that IP. Then you use select() or poll() to wait for requests on all sockets at once. When a request comes in on a particular socket, you send the reply out through that same socket, and its source IP will match the original packet's destination.