How to "Interconnect" Two Sockets in Linux

How can I interconnect two sockets in Linux?

Are you aware of splice(). Based on your two questions I think this is where you are headed. Last I checked you can't do this in one splice call because both of file descriptors can't be sockets. But you should be able to do it in 2 calls (sockin->pipe->sockout). Also take a look at tee(). These may not be exactly what you want but from what I can figure they are in the ballpark.

Joining 2 Sockets?

AFAIK, It is not possible.

A simple example: If your processes runs on three different machines, how could the proxy machine step aside without involving traffic redirection at TCP/UDP/whatever level?

splice is not a solution, it simply optimizes the i/o transfer avoiding unnecessary memory copies but, in any case, you need a process that cycles on input and call splice to "transfer" data to output (and if the sockets are real network sockets, the data have to pass twice through the network card).

LLP, Andrea

Need multiple connections in C socket

When a client disconnects you create a new server socket and bind it to the same port. If the server side socket was not closed the port is still in use, so bind fails.

Usually the server side of a socket program has a loop around accept to allow it process connections from many clients. This way bind and listen are called only once.

while (connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size1)) {
printf("\n I got a connection from (%s , %d)",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
bytes_recieved = recv(connected,recv_data,1024,0);
recv_data[bytes_recieved] = '\0';
send(connected, ser_data,50, 0);
close(connected);
}

Is it possible to connect two pipes/sockets?

If you simply want to read from one socket and write to another without copying the data to user-space, look at http://linux.die.net/man/2/sendfile . You need a fairly recent Linux.

Can a server open two TCP sockets in c?


I have a server that listens for incoming connections and processes
the data from a client. Then, on the same server, I want to open
another TCP sockets that send the data to another server without using
the set socket() option.

There is no specific limit on the number of unconnected, connected, and listening sockets that a system or an individual process may have open at any given time. It is routine for a system to have many, and not uncommon for individual processes to have more than one.

But you need to understand that each socket is represented by a specific file descriptor number (or even by more than one). The same file descriptor cannot refer to two different sockets at the same time. Furthermore, the same socket cannot be both connected and listening.

The socket() function is used to create a socket. From there, for a TCP socket, your options are to either

  • connect() it to a peer, OR
  • use it to listen() for and accept() connections from peers.

You cannot use the same socket for both. Instead, create separate sockets via socket() for listening and for initiating connections. Create multiple of each if you want to listen on multiple ports or connect to multiple peers.

UDP Networking with multiple sockets

As the comments suggested, you can monitor multiple ports with the select function. It takes lists of ports to check for readability, writability, or errors and returns lists of ports in the requested state.

Below is an example watching 5 ports for readability, and exits when all 5 ports have received something:

import socket
import select

N = 5
base_port = 5000

# Create N sockets and bind to ports 5000 to 5000+N-1:
socks = [socket.socket(type=socket.SOCK_DGRAM) for _ in range(N)]
for i,s in enumerate(socks):
s.bind(('',base_port+i))

# Flags to track that something was received on a particular port
got = [False] * N

while not all(got):
# Watch all N sockets for readability only
readable,writable,errors = select.select(socks,[],[])

# Only a socket that has something to read will be in "readable"
for s in readable:
port = s.getsockname()[1] # which port was it
data,addr = s.recvfrom(4096)
print(f'From {port}: {data}')
got[port-5000] = True

print("Got'em all!")

Demo (client)

>>> from socket import *
>>> s=socket(type=SOCK_DGRAM)
>>> s.sendto(b'abc',('localhost',5001))
3
>>> s.sendto(b'abc',('localhost',5002))
3
>>> s.sendto(b'abc',('localhost',5003))
3
>>> s.sendto(b'abc',('localhost',5004))
3
>>> s.sendto(b'abc',('localhost',5000))
3

Demo (server)

From 5001: b'abc'
From 5002: b'abc'
From 5003: b'abc'
From 5004: b'abc'
From 5000: b'abc'
Got'em all!

sharing sockets between processes on linux

If you want to avoid copy overhead you should probably be using splice, rather than trying to share sockets between multiple daemons. That solution is going to be fiendishly difficult to debug and maintain.

I expect (and hope) that your network protocol has a header which makes it easy for the gateway to know where to route a packet to, followed by a payload destined for the service daemon.

In pseudocode the gateway does this:

while (data on socket)
{
header = read(socket, sizeof(header));

service_socket = find_service(header);
splice(socket, NULL, service_socket, NULL, header->payload_length, 0);
}


Related Topics



Leave a reply



Submit